Skip to content

Commit

Permalink
Security API change: remove chip-to-chip security and end-to-end encr…
Browse files Browse the repository at this point in the history
…yption services. (#921)

The chip-to-chip security and end-to-end encryption services are no longer supported by u-blox and hence are removed.

NOTE: this ends up reducing the required cellular UART buffer length from more than 2 kbytes to just over 1 kbyte, since the governing factor was chip-to-chip encryption.
  • Loading branch information
RobMeades committed Jun 23, 2023
1 parent 84565ee commit 2639236
Show file tree
Hide file tree
Showing 36 changed files with 194 additions and 6,175 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,7 @@ A number of examples are provided with this repo:
| Technology | Example |
|--------------|----------|
| Cellular | The [sockets](/example/sockets "socket example") example brings up a TCP/UDP socket by using the [device](/common/device "device API"), [network](/common/network "network API") and [sock](/common/sock "sock API") APIs. |
| Cellular | The [end-to-end security](/example/security/e2e "E2E example") example using the [security](/common/security "security API") API. |
| Cellular | The [PSK generation](/example/security/psk "PSK example") example using the [security](/common/security "security API") API. |
| Cellular | The [chip-to-chip security](/example/security/c2c "C2C example") example using the [security](/common/security "security API") API. |
| Cellular | A [TLS-secured version](/example/sockets "TLS sockets example") of the sockets example. |
| Cellular | An [MQTT/MQTT-SN client](/example/mqtt_client "MQTT/MQTT-SN example") using the [MQTT/MQTT-SN client](/common/mqtt_client "MQTT/MQTT-SN client API") API.|
| Cellular | An [HTTP client](/example/http_client "HTTP example") using the [HTTP client](/common/http_client "HTTP client API") API.|
Expand Down
20 changes: 3 additions & 17 deletions cell/api/u_cell.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,16 @@ extern "C" {
/** The recommended UART buffer length for the cellular driver,
* large enough to run AT sockets using the IP stack on the
* cellular module (where the maximum packet length is 1024 bytes)
* without flow control. See #U_CELL_AT_BUFFER_LENGTH_BYTES for
* where the overhead numbers come from (for the C2C case).
* without flow control.
*/
# define U_CELL_UART_BUFFER_LENGTH_BYTES (1024 + 16 + 16 + 16 + 16 + 16 + 6)
# define U_CELL_UART_BUFFER_LENGTH_BYTES 1024
#endif

#ifndef U_CELL_AT_BUFFER_LENGTH_BYTES
/** The AT client buffer length required in the AT client by the
* cellular driver.
*
* When chip to chip security is employed the size of each
* secure frame adds a considerable overhead. Maximum
* chunk size is 1024 + 16 bytes (for an AT command,
* see u_cell_sec_c2c.h) plus the maximum padding length of 16,
* bytes plus the length of a truncated MAC (16 bytes) plus the
* length of the initial value (16 bytes) plus the length of
* the HMAC SHA tag for the V2 scheme (16 bytes) plus
* start/length/CRC/stop field totalling 6 bytes. Then it is
* possible for there to be part of one of these in the buffer
* being processed by the AT client when another is meant to
* turn up so allow for at least two.
*/
# define U_CELL_AT_BUFFER_LENGTH_BYTES (U_AT_CLIENT_BUFFER_OVERHEAD_BYTES + \
((1024 + 16 + 16 + 16 + 16 + 16 + 6) * 2))
# define U_CELL_AT_BUFFER_LENGTH_BYTES (U_AT_CLIENT_BUFFER_LENGTH_BYTES + U_CELL_UART_BUFFER_LENGTH_BYTES)
#endif

#ifndef U_CELL_UART_BAUD_RATE
Expand Down
4 changes: 0 additions & 4 deletions cell/api/u_cell_mux.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@ void uCellMuxPrivateLink(void);
* uCellAtClientHandleGet(); uCellAtClientHandleGet() will always
* return the AT handle currently in use.
*
* Multiplexer mode cannot be enabled while chip-to-chip security
* is active, however chip-to-chip security can be enabled _after_
* multiplexer mode has been enabled.
*
* Whether multiplexer mode is supported or not depends on the cellular
* module and the interface in use: for instance a USB interface to
* a module does not support multiplexer mode.
Expand Down
193 changes: 11 additions & 182 deletions cell/api/u_cell_sec.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,96 +128,6 @@ int32_t uCellSecGetSerialNumber(uDeviceHandle_t cellHandle,
int32_t uCellSecGetRootOfTrustUid(uDeviceHandle_t cellHandle,
char *pRootOfTrustUid);

/* ----------------------------------------------------------------
* FUNCTIONS: CHIP TO CHIP SECURITY
* -------------------------------------------------------------- */

/** Pair a cellular module's AT interface with this MCU for chip to
* chip security. This feature is available by arrangement with
* u-blox. The pairing process is expected to be carried out in a
* secure production environment *before* the device is boostrapped,
* i.e. before the module is allowed to contact the u-blox security
* services over the network. Only if a special feature,
* "LocalC2CKeyPairing", is enabled in the u-blox security service
* can pairing be carried out after a device has been sealed, since
* this represents a potential attack vector.
*
* Once this function returns successfully the values of the locally
* generated pTESecret and the pKey and pHMac parameters returned must
* be stored securely on this MCU by the caller. Later, after the
* module has bootstrapped and been sealed the parameters may be used
* in a call to uSecurityC2cOpen() to encrypt communication over the
* AT interface between this MCU and the module.
*
* @param cellHandle the handle of the instance to be used.
* @param[in] pTESecret a pointer to the fixed-length 16 byte
* secret generated by this MCU (the
* "Terminal Equipment") to be used in the
* pairing process; cannot be NULL.
* @param[out] pKey a place to store the fixed-length 16 byte
* encryption key that must be used when a
* secure AT session is opened. It is up to
* the caller to store this securely in
* non-volatile memory for future use.
* Cannot be NULL.
* @param[out] pHMacKey a place to store the fixed-length
* 16 byte HMAC key that must be used when a
* secure AT session is opened. It is up
* to the caller to store this securely in
* non-volatile memory for future use.
* Cannot be NULL.
* @return zero on success else negative error code.
*/
int32_t uCellSecC2cPair(uDeviceHandle_t cellHandle,
const char *pTESecret,
char *pKey, char *pHMacKey);

/** Open a secure AT session. Once this has returned
* successfully the AT client will encrypt the outgoing data
* stream to the cellular module and decrypt data received back from
* the cellular module using the keys provided. pTeSecret, pKey,
* and pHMax are provided from non-volatile storage on the
* MCU, the latter two resulting from the C2C pairing process
* carried out earlier. Once this function returns successfully
* all AT communications will be encrypted by the AT client until
* uSecurityC2cClose() is called or the cellular module is powered
* off or rebooted. If a chip to chip security session is
* already open when this is called it will do nothing and
* return success.
*
* Should chip to chip security have somehow failed the cellular
* module will appear as though it is unresponsive. If this
* happen use hard power off, uCellPwrOffHard() (but no need
* for "trulyHard"), which uses electrical rather than AT-command
* means to power the module down, and then restart it to try again.
*
* @param cellHandle the handle of the instance to be used.
* @param[in] pTESecret a pointer to the fixed-length 16 byte
* secret key that was used during pairing;
* cannot be NULL.
* @param[in] pKey a pointer to the fixed-length 16 byte
* encryption key that was returned during
* pairing; cannot be NULL.
* @param[in] pHMacKey a pointer to the fixed-length 16 byte
* HMAC key that was returned during pairing;
* cannot be NULL.
* @return zero on success else negative error code.
*/
int32_t uCellSecC2cOpen(uDeviceHandle_t cellHandle,
const char *pTESecret,
const char *pKey,
const char *pHMacKey);

/** Close a secure AT session. Once this has returned
* successfully the AT exchange with the cellular module will
* once more be unencrypted. If there is no open C2C session
* this function will do nothing and return success.
*
* @param cellHandle the handle of the instance to be used.
* @return zero on success else negative error code.
*/
int32_t uCellSecC2cClose(uDeviceHandle_t cellHandle);

/* ----------------------------------------------------------------
* FUNCTIONS: SEAL
* -------------------------------------------------------------- */
Expand All @@ -232,14 +142,9 @@ int32_t uCellSecC2cClose(uDeviceHandle_t cellHandle);
*
* @param cellHandle the handle of the cellular instance.
* @param[in] pDeviceProfileUid the null-terminated device profile
* UID string provided by u-blox.
* Note: if you have activated your module
* via the Thingstream portal
* (https://portal.thingstream.io) then the
* device profile UID string is visible
* once you have created a device profile
* for your module; it will look something
* like "AgbCtixjwqLjwV3VWpfPyz".
* UID string provided by u-blox; it will
* look something like
* "AgbCtixjwqLjwV3VWpfPyz".
* @param[in] pDeviceSerialNumberStr the null-terminated device serial
* number string; you may chose what this
* is, noting that there may be an upper
Expand Down Expand Up @@ -287,7 +192,7 @@ bool uCellSecIsSealed(uDeviceHandle_t cellHandle);
* during the sealing process. If the certificate does not [yet]
* exist an error will be returned. This feature is only
* supported if the Zero Touch Provisioning feature is enabled
* in your Thingstream portal for the module.
* for your module.
*
* If pData is set to NULL then the number of bytes required to
* store the certificate, including a null terminator, will still
Expand All @@ -300,11 +205,6 @@ bool uCellSecIsSealed(uDeviceHandle_t cellHandle);
* flow control lines are connected on the interface to the
* module.
*
* Note that if the chip-to-chip security feature is enabled
* in the Thingstream portal for a module then a chip-to-chip
* security session must have been opened before this function is
* called, otherwise it will return an error.
*
* @param cellHandle the handle of the cellular instance.
* @param[out] pData a pointer to somewhere to store
* the certificate; use NULL to
Expand All @@ -325,8 +225,7 @@ int32_t uCellSecZtpGetDeviceCertificate(uDeviceHandle_t cellHandle,
/** Read the device private key that was generated during the
* sealing process. If the key does not [yet] exist an error
* will be returned. This feature is only supported if the Zero
* Touch Provisioning feature is enabled in your Thingstream
* portal for the module.
* Touch Provisioning feature is enabled for your module.
*
* If pData is set to NULL then the number of bytes required to
* store the key, including a null terminator, will still be
Expand All @@ -339,11 +238,6 @@ int32_t uCellSecZtpGetDeviceCertificate(uDeviceHandle_t cellHandle,
* flow control lines are connected on the interface to the
* module.
*
* Note that if the chip-to-chip security feature is enabled
* in the Thingstream portal for a module then a chip-to-chip
* security session must have been opened before this function is
* called, otherwise it will return an error.
*
* @param cellHandle the handle of the cellular instance.
* @param[out] pData a pointer to somewhere to store
* the key; use NULL to just get the
Expand All @@ -365,7 +259,7 @@ int32_t uCellSecZtpGetPrivateKey(uDeviceHandle_t cellHandle,
* the sealing process. If the certificate(s) do not [yet]
* exist an error will be returned. This feature is only
* supported if the Zero Touch Provisioning feature is enabled
* in your Thingstream portal for the module.
* for your module.
*
* If pData is set to NULL then the number of bytes required to
* store the certificates, including a null terminator, will still
Expand All @@ -378,11 +272,6 @@ int32_t uCellSecZtpGetPrivateKey(uDeviceHandle_t cellHandle,
* flow control lines are connected on the interface to the
* module.
*
* Note that if the chip-to-chip security feature is enabled
* in the Thingstream portal for a module then a chip-to-chip
* security session must have been opened before this function is
* called, otherwise it will return an error.
*
* @param cellHandle the handle of the cellular instance.
* @param[out] pData a pointer to somewhere to store
* the certificate authorities; use
Expand All @@ -400,66 +289,6 @@ int32_t uCellSecZtpGetCertificateAuthorities(uDeviceHandle_t cellHandle,
char *pData,
size_t dataSizeBytes);

/* ----------------------------------------------------------------
* FUNCTIONS: END TO END ENCRYPTION
* -------------------------------------------------------------- */

/** Set the E2E encryption version to be used. Not all cellular
* module types support all versions: refer to the AT manual for your
* cellular module to determine what's what. If a cellular module
* only supports a single E2E encryption type then it probably won't
* support setting the E2E encryption version.
*
* @param cellHandle the handle of the instance to be used.
* @param version the version to use; use 1 for version 1,
* etc. (so there is no version 0).
* @return zero on success else negative error code.
*/
int32_t uCellSecE2eSetVersion(uDeviceHandle_t cellHandle, int32_t version);

/** Get the E2E encryption version. If a cellular module only supports
* a single E2E encryption type then it may not support getting the
* E2E encryption version. Note that while the AT+USECOPCMD="e2e_enc"
* command returns 0 for version 1 etc., this function will return
* 1 for version 1, i.e. there is no version 0.
*
* @param cellHandle the handle of the instance to be used.
* @return on success the E2E encryption version,
* else negative error code.
*/
int32_t uCellSecE2eGetVersion(uDeviceHandle_t cellHandle);

/** Ask a cellular module to encrypt a block of data. For this to
* work the module must have previously been security sealed but no
* current connection is required. Data encrypted in this way
* can be decrypted on arrival at its destination by requesting
* the relevant security keys from u-blox via the security services
* web API.
*
* @param cellHandle the handle of the instance to be used.
* @param[in] pDataIn a pointer to dataSizeBytes of data to be
* encrypted, may be NULL, in which case this
* function does nothing.
* @param[out] pDataOut a pointer to a location to store the
* encrypted data that MUST BE at least of
* size dataSizeBytes +
* #U_SECURITY_E2E_V1_HEADER_LENGTH_BYTES for
* E2E encryption version 1 or dataSizeBytes +
* #U_SECURITY_E2E_V2_HEADER_LENGTH_BYTES for
* E2E encryption version 2 (or you can
* just use #U_SECURITY_E2E_HEADER_LENGTH_MAX_BYTES
* for both cases); can only be NULL if pDataIn
* is NULL.
* @param dataSizeBytes the number of bytes of data to encrypt;
* must be zero if pDataIn is NULL.
* @return on success the number of bytes in the
* encrypted data block else negative error
* code.
*/
int32_t uCellSecE2eEncrypt(uDeviceHandle_t cellHandle,
const void *pDataIn,
void *pDataOut, size_t dataSizeBytes);

/* ----------------------------------------------------------------
* FUNCTIONS: PRE-SHARED KEY GENERATION
* -------------------------------------------------------------- */
Expand Down Expand Up @@ -492,11 +321,11 @@ int32_t uCellSecPskGenerate(uDeviceHandle_t cellHandle,

/** Trigger a security heartbeat: this is useful if modifications
* have been made to the security profile of the device in the
* u-blox security services REST API (or through the Thingstream
* service) and the device needs to be updated with these changes.
* HOWEVER, note that rate limiting is applied to these adhoc security
* hearbeats and hence if requested too frequently (e.g. more than
* once every 24 hours) the trigger request may return an error.
* u-blox security services REST API and the device needs to be
* updated with these changes. HOWEVER, note that rate limiting is
* applied to these adhoc security hearbeats and hence if requested
* too frequently (e.g. more than once every 24 hours) the trigger
* request may return an error.
*
* @param cellHandle the handle of the instance to be used, for
* example obtained through uDeviceOpen().
Expand Down
2 changes: 0 additions & 2 deletions cell/src/u_cell.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ static void removeCellInstance(uCellPrivateInstance_t *pInstance)
uAtClientSetWakeUpHandler(pInstance->atHandle, NULL, NULL, 0);
// Free any scan results
uCellPrivateScanFree(&(pInstance->pScanResults));
// Free any chip to chip security context
uCellPrivateC2cRemoveContext(pInstance);
// Free any location context and associated URC
uCellPrivateLocRemoveContext(pInstance);
// Free any sleep context
Expand Down

0 comments on commit 2639236

Please sign in to comment.