Arduino LMIC 6.0.1
Arduino LoRaWAN(r) MAC in C
Loading...
Searching...
No Matches
LMIC Secure Element default implementation

This module provides a default Secure Element to the LMIC. More...

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_initialize (void)
 Initialize the Secure Element.
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_setDevEUI (const LMIC_SecureElement_EUI_t *pDevEUI)
 Set device EUI.
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_setAppEUI (const LMIC_SecureElement_EUI_t *pAppEUI)
 Set application EUI.
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_setAppKey (const LMIC_SecureElement_Aes128Key_t *pAppKey)
 Set application key.
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_getNwkSKey (LMIC_SecureElement_Aes128Key_t *pNwkSKey, LMIC_SecureElement_KeySelector_t iKey)
 Get network session key.
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_getAppSKey (LMIC_SecureElement_Aes128Key_t *pAppSKey, LMIC_SecureElement_KeySelector_t iKey)
 Get application session key.
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_verifyMIC (const uint8_t *pPhyPayload, uint8_t nPhyPayload, uint32_t devAddr, uint32_t FCntDown, LMIC_SecureElement_KeySelector_t iKey)
 Calculate and check the MIC for a downlink packet (default driver).
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_encodeMessage (const uint8_t *pMessage, uint8_t nMessage, uint8_t iPayload, uint8_t *pCipherTextBuffer, LMIC_SecureElement_KeySelector_t iKey)
 Encode an uplink packet (default driver).
LMIC_SecureElement_Error_t LMIC_ABI_STD LMIC_SecureElement_Default_decodeMessage (const uint8_t *pPhyPayload, uint8_t nPhyPayload, uint32_t devAddr, uint32_t FCntDown, LMIC_SecureElement_KeySelector_t iKey, uint8_t *pClearTextBuffer)
 Decode a received message (default driver).
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_createJoinRequest (uint8_t *pJoinRequestBytes, LMIC_SecureElement_JoinFormat_t joinFormat)
 Prepare a join request packet (default driver).
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_decodeJoinAccept (const uint8_t *pJoinAcceptBytes, uint8_t nJoinAcceptBytes, uint8_t *pJoinAcceptClearText, LMIC_SecureElement_JoinFormat_t joinFormat)
 Decode a join accept packet (default driver).
LMIC_SecureElement_Error_t LMIC_SecureElement_Default_aes128Encrypt (const uint8_t *pKey, const uint8_t *pInput, uint8_t *pOutput)
 Perform an AES128 encryption.

Detailed Description

This module provides a default Secure Element to the LMIC.

Many applications of LoRaWAN have no need for elaborate security mechanisms, and only require that the over the air security be implemented correctly and efficiently. The Default Secure Element implementation may be useful in such cases. Keys are not stored internally, and the AES encryption mechanisms are not necessarily robust against differential black-box or sideband attacks. Still, if unique keys are used in the device and carefully managed, they may provide adequate security.

The default provider does not use non-volatile storage. It is the implementation's responsibility to provide keys and credentials to the default Secure Element whenever the system boots up.

Function Documentation

◆ LMIC_SecureElement_Default_aes128Encrypt()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_aes128Encrypt ( const uint8_t * pKey,
const uint8_t * pInput,
uint8_t * pOutput )

Perform an AES128 encryption.

Parameters
pKey[in] Encryption key (16 bytes).
pInput[in] Clear text (16 bytes).
pOutput[out] Cipher text (16 bytes).

This API is used for beacon calculations and other pseudo-random operations. Key, input buffer, output buffer are all 16 bytes long. pOutput and pInput may be the same buffer; otherwise they must point to non-overlapping regions of memory. pKey must not overlap pOutput. None of pKey, pInput, pOutput may be NULL.

Return values
LMIC_SecureElement_Error_OKif the encryption was performed
LMIC_SecureElement_Error_InvalidParameterif any of the parameters is invalid.
Implementation Details
This implementation uses os_aes() to do the encryption, which is mapped either to os_aes_original() or os_aes_generic(), depending on the AES engine selected at compile time.
Postcondition
AESKey is set to the contents of pKey.

References LMIC_SecureElement_Error_OK, and os_copyMem.

◆ LMIC_SecureElement_Default_createJoinRequest()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_createJoinRequest ( uint8_t * pJoinRequestBytes,
LMIC_SecureElement_JoinFormat_t joinFormat )

Prepare a join request packet (default driver).

Parameters
pJoinRequestBytes[out] Buffer to be filled with the join request.
joinFormat[in] Join type selector.

The buffer at * pJoinRequestBytes must be at least sizeof(LMIC_SecureElement_JoinRequest_t::bytes) long; it is filled with a JoinRequest message, encrypted with the keys suitable to the specified context. joinFormat is provided for future use in LoRaWAN 1.1 systems; it selects the keys to be used and the format of the message. It shall be set to LMIC_SecureElement_JoinFormat_JoinRequest10.

Returns
The result is LMIC_SecureElement_Error_OK for success, some other value for failure.
Return values
LMIC_SecureElement_Error_InvalidParameterindicates that iKey was not valid.
Implementation Details
This implementation only supports joinFormat == LMIC_SecureElement_JoinFormat_JoinRequest10.

References LMIC_SecureElement_Error_InvalidParameter, LMIC_SecureElement_Error_OK, LMIC_SecureElement_JoinFormat_JoinRequest10, and os_wlsbf2().

◆ LMIC_SecureElement_Default_decodeJoinAccept()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_decodeJoinAccept ( const uint8_t * pJoinAcceptBytes,
uint8_t nJoinAcceptBytes,
uint8_t * pJoinAcceptClearText,
LMIC_SecureElement_JoinFormat_t joinFormat )

Decode a join accept packet (default driver).

Parameters
pJoinAcceptBytes[in] Buffer with raw join accept message
nJoinAcceptBytes[in] Number of bytes
pJoinAcceptClearText[out] Buffer to be filled with decrypted message; same size as pJoinAcceptBytes.
joinFormat[in] Type used on message that triggered this join accept.

The Join-Accept message is decoded using the keys designated by the joinFormat, and the clear text is placed in pJoinAcceptClearText.

The LMIC presently only supports LoRaWAN 1.0.3, so joinFormat must be LMIC_SecureElement_JoinFormat_JoinRequest10.

Returns
The result is LMIC_SecureElement_Error_OK for success, some other value for failure. If successful, the appropriate session keys are generated and stored in the secure element.
Implementation Details
This implementation only supports joinFormat == LMIC_SecureElement_JoinFormat_JoinRequest10.

References LMIC_SecureElement_Error_InvalidMIC, LMIC_SecureElement_Error_InvalidParameter, LMIC_SecureElement_Error_OK, LMIC_SecureElement_JoinFormat_JoinRequest10, and os_copyMem.

◆ LMIC_SecureElement_Default_decodeMessage()

LMIC_SecureElement_Error_t LMIC_ABI_STD LMIC_SecureElement_Default_decodeMessage ( const uint8_t * pPhyPayload,
uint8_t nPhyPayload,
uint32_t devAddr,
uint32_t FCntDown,
LMIC_SecureElement_KeySelector_t iKey,
uint8_t * pClearTextBuffer )

Decode a received message (default driver).

Parameters
pPhyPayload[in] Pointer to MHDR byte of received PHY message.
nPhyPayload[in] Number of bytes, including the MIC.
devAddr[in] Device address
FCntDown[in] The downlink frame counter to be used with this message
iKey[in] Key discriminator.
pClearTextBuffer[out] Buffer to be used for the output data. Must be nPhyPayload - 4 bytes long.

The payload is decrypted and placed in pClearTextBuffer. The MIC is assumed to be valid. The output buffer must be nBuffer - 4 bytes long (the MIC is not appended). ClearTextdBuffer may be the same as pPhyPayload, in which case the update is done in-place if possible. Otherwise the input and output blocks shall be strictly non-overlapping.

Returns
Returns LMIC_SecureElement_Error_OK for success, some other value for failure.
Implementation Details
  • This implementation only supports iKey == LMIC_SecureElement_KeySelector_Unicast.
  • The API forces us to do a little extra work, by reaching into the message to find the port number. We are careful not to index off the buffer, but we don't examine the message structure in detail.

References LMIC_SecureElement_Error_InvalidParameter, LMIC_SecureElement_Error_OK, LMIC_SecureElement_KeySelector_Unicast, and os_copyMem.

◆ LMIC_SecureElement_Default_encodeMessage()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_encodeMessage ( const uint8_t * pMessage,
uint8_t nMessage,
uint8_t iPayload,
uint8_t * pCipherTextBuffer,
LMIC_SecureElement_KeySelector_t iKey )

Encode an uplink packet (default driver).

Parameters
pMessage[in] Pointer to MHDR byte of message to encode.
nMessage[in] Number of bytes, not including the MIC.
iPayload[in] Index of payload field in the message.
pCipherTextBuffer[in] Pointer to buffer to receive phy message.
iKey[in] Key discriminator.

The output buffer must be nBuffer + 4 bytes long. FCntUp in the message may be ignored by the Secure Element and replaced by SE's idea of the uplink frame count. SE will increment its internal FCntUp. To implement NbTrans > 1, caller shall cache the encoded message and retransmit it, rather than re-encoding it. pCipherTextBuffer may be the same as pMessage; in this case the update is done in-place if possible. Otherwise the blocks shall be strictly non-overlapping.

Returns
The result is LMIC_SecureElement_Error_OK for success, some other value for failure.
Implementation Details
This implementation assumes that the message is formatted correctly; which means that iPayload, if less than nMessage, is taken as the index of the port number. This is used to select either AppSKey or NwkSKey to encode and MIC the message.
Return values
LMIC_SecureElement_Error_OKmeans that the MIC was valid.
LMIC_SecureElement_Error_InvalidMICmeans that the MIC was not valid.

References LMIC_SecureElement_Error_InvalidParameter, LMIC_SecureElement_Error_OK, LMIC_SecureElement_KeySelector_Unicast, and os_copyMem.

◆ LMIC_SecureElement_Default_getAppSKey()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_getAppSKey ( LMIC_SecureElement_Aes128Key_t * pAppSKey,
LMIC_SecureElement_KeySelector_t iKey )

Get application session key.

Parameters
pAppSKey[out] set to the value of the application session key.
iKey[in] key discriminator.
Returns
LMIC_SecureElement_Error_OK for success, some other code for failure. Many secure elements will fail this request, because their purpose in life is guarding keys and preventing tampering.
Implementation Notes
In the default secure element, the appskey is stored in a static variable without obfuscation. In this function the appskey is passed to upper layer of LMIC.

References LMIC_SecureElement_Aes128Key_s::bytes, LMIC_SecureElement_Error_InvalidParameter, LMIC_SecureElement_Error_OK, LMIC_SecureElement_KeySelector_Unicast, and os_copyMem.

◆ LMIC_SecureElement_Default_getNwkSKey()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_getNwkSKey ( LMIC_SecureElement_Aes128Key_t * pNwkSKey,
LMIC_SecureElement_KeySelector_t iKey )

Get network session key.

Parameters
pNwkSKey[in] provides the value of the network session key.
iKey[in] key discriminator.
Returns
LMIC_SecureElement_Error_OK for success, some other code for failure. Many secure elements will fail this request, because their purpose in life is guarding keys and preventing tampering.
Implementation Notes
In the default secure element, the nwkskey is stored in a static variable without obfuscation. In this function the nwkskey is passed to upper layer of LMIC.

References LMIC_SecureElement_Aes128Key_s::bytes, LMIC_SecureElement_Error_InvalidParameter, LMIC_SecureElement_Error_OK, LMIC_SecureElement_KeySelector_Unicast, and os_copyMem.

◆ LMIC_SecureElement_Default_initialize()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_initialize ( void )

Initialize the Secure Element.

Returns
LMIC_SecureElement_Error_OK for success, some other code for failure.
Implementation Notes
Initialize the default secure-element implementation for the LMIC. The API contract for the secure element requires that the LMIC call this function once during initialization.
Returns
The default implementation always succeeds.

References LMIC_SecureElement_Error_OK.

◆ LMIC_SecureElement_Default_setAppEUI()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_setAppEUI ( const LMIC_SecureElement_EUI_t * pAppEUI)

Set application EUI.

Parameters
pAppEUI[in] application EUI for this secure element.
Returns
LMIC_SecureElement_Error_OK for success, some other code for failure.
Implementation Notes
In the default secure element, the app EUI is stored in a static variable without obfuscation.

References LMIC_SecureElement_Error_OK.

◆ LMIC_SecureElement_Default_setAppKey()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_setAppKey ( const LMIC_SecureElement_Aes128Key_t * pAppKey)

Set application key.

Parameters
pAppKey[in] Points to 16-byte application key.
Returns
LMIC_SecureElement_Error_OK for success, some other code for failure.
Implementation Notes
In the default secure element, the appkey is stored in a static variable without obfuscation.

References LMIC_SecureElement_Error_OK.

◆ LMIC_SecureElement_Default_setDevEUI()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_setDevEUI ( const LMIC_SecureElement_EUI_t * pDevEUI)

Set device EUI.

Parameters
pDevEUI[in] Device key for this secure element.
Returns
LMIC_SecureElement_Error_OK for success, some other code for failure.
Implementation Notes
In the default secure element, the device EUI is stored in a static variable without obfuscation.

References LMIC_SecureElement_Error_OK.

◆ LMIC_SecureElement_Default_verifyMIC()

LMIC_SecureElement_Error_t LMIC_SecureElement_Default_verifyMIC ( const uint8_t * pPhyPayload,
uint8_t nPhyPayload,
uint32_t devAddr,
uint32_t FCntDown,
LMIC_SecureElement_KeySelector_t iKey )

Calculate and check the MIC for a downlink packet (default driver).

Parameters
pPhyPayload[in] Pointer to MHDR byte of received PHY message.
nPhyPayload[in] Number of bytes, including the MIC.
devAddr[in] Device address
FCntDown[in] The downlink frame counter to be used with this message
iKey[in] Key discriminator.

The MIC code for the message is calculated using the appropriate key and algorithm.

Returns
Returns LMIC_SecureElement_Error_OK if the MIC matched, or an error code related to the failure. Secure Element drivers are not rigorously tested to return the same error codes in all situations, so any result other than LMIC_SecureElement_Error_OK must be treated as an error.
Implementation Details
This implementation requires that iKey be LMIC_SecureElement_KeySelector_Unicast.
Return values
LMIC_SecureElement_Error_OKmeans that the MIC was valid.
LMIC_SecureElement_Error_InvalidMICmeans that the MIC was not valid.

References LMIC_SecureElement_Error_InvalidMIC, LMIC_SecureElement_Error_InvalidParameter, LMIC_SecureElement_Error_OK, and LMIC_SecureElement_KeySelector_Unicast.