This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF9160 LwM2M sample app: cannot update DTLS keys dynamically

Hi,

I have extended the nRF9160 sample app to use Leshan bootstrap server. Using a boostrap server means getting DTLS PSK crypto keys from the bootstrap server. Hence the device must be able to update the keys while connecting. However, it seems this is not supported by the system:

1) The IP stack is offloaded in the sample app (CONFIG_NET_SOCKETS_OFFLOAD=y), meaning it is deployed on the modem to my understanding!?

2) The sample app writes keys at startup (before connecting to the network) thru function nrf_inbuilt_key_write(). The documentation of this function states: "Run this function only when LTE link is inactive. If used during active link, NRF_EACCES will be returned and the key material will not be written."

3) Since it is not possible to write/update keys when connected it is not possible to implement the bootstrap server scenario efficiently!

Please advice regarding the above limitations! How do you envision that the bootstrap server scenario shall be implemented?

I am using the nRF Connect SDK version 1.1.0.

BR / Björn

Parents
  • Hi.

     

    The IP stack is offloaded in the sample app (CONFIG_NET_SOCKETS_OFFLOAD=y), meaning it is deployed on the modem to my understanding!?

     That is correct.

     

    How do you envision that the bootstrap server scenario shall be implemented?

     You would have to disconnect from the network after receiving the keys, store them, and then reconnect to the network.

    That is the only way I can think  of at the moment.

    Best regards,

    Didrik

  • Hi Didrik,

    Thanks for your response. I have been at a biz trip so I have not been able to respond.

    Regarding your implementation advice: it is not possible to disconnect, store key and connect again due to the way the LwM2M client is working in your platform. When I reconnect the LwM2M client will always go to the bootstrap server meaning I can get a new key...so I am stuck in an infinite loop. To fix this I need to patch your LwM2M client which I want to avoid.

    Questions:

    1) Why is it not possible to change keys when connected? Security?

    2) Do you have any plans to open for key change when connected?

    BR / Björn

  • Bjorn191023 said:
    Regarding your implementation advice: it is not possible to disconnect, store key and connect again due to the way the LwM2M client is working in your platform. When I reconnect the LwM2M client will always go to the bootstrap server meaning I can get a new key...so I am stuck in an infinite loop.

     I have not used the LwM2M client a lot, but can you not write a function that disconnects, write the PSK and connect, then provide a pointer to that function in the load_credentials field in the lwm2m_ctx struct?

     

    Bjorn191023 said:

    1) Why is it not possible to change keys when connected? Security?

    2) Do you have any plans to open for key change when connected?

     This is because of timing restrictions in the modem. As a certificate can be quite large, it is not guaranteed that the modem is able to write it to flash (which takes time) while simultaneously upholding the timing demands of the cellular network.

  • Hi Didrik,

     I have not used the LwM2M client a lot, but can you not write a function that disconnects, write the PSK and connect, then provide a pointer to that function in the load_credentials field in the lwm2m_ctx struct?

    To my understanding it is not possible. If I disconnect on low level then the DTLS session will be invalidated, meaning that we need to reconnect to "coaps://<url>:<port>". The only way to that with the LwM2M client is to "restart". Doing what you propose would require a change of the LwM2M client API .

    This is because of timing restrictions in the modem. As a certificate can be quite large, it is not guaranteed that the modem is able to write it to flash (which takes time) while simultaneously upholding the timing demands of the cellular network.

    Ok, I know that problem :-) so the reason is understood. However, I have a proposal. The bootstrap server use cases gives a session key by design. A session key is volatile while the modem only stores non-volatile keys. I propose to add the possibility to store volatile keys in the modem. This would support the LwM2M boostrap server use case out of the box. 

    BR / Björn

Reply
  • Hi Didrik,

     I have not used the LwM2M client a lot, but can you not write a function that disconnects, write the PSK and connect, then provide a pointer to that function in the load_credentials field in the lwm2m_ctx struct?

    To my understanding it is not possible. If I disconnect on low level then the DTLS session will be invalidated, meaning that we need to reconnect to "coaps://<url>:<port>". The only way to that with the LwM2M client is to "restart". Doing what you propose would require a change of the LwM2M client API .

    This is because of timing restrictions in the modem. As a certificate can be quite large, it is not guaranteed that the modem is able to write it to flash (which takes time) while simultaneously upholding the timing demands of the cellular network.

    Ok, I know that problem :-) so the reason is understood. However, I have a proposal. The bootstrap server use cases gives a session key by design. A session key is volatile while the modem only stores non-volatile keys. I propose to add the possibility to store volatile keys in the modem. This would support the LwM2M boostrap server use case out of the box. 

    BR / Björn

Children
  • Hi.

    I have asked the NCS team if they know of any way around the LwM2M client's limitations.

    I'll come back to you when I get a reply.

    Best regards,

    Didrik

  • Hi, and sorry for the wait.

    Here is the reply I got from the NCS team:

    I don't agree with the customer argumentation regarding `load_credentials`. When this function is called by the LWM2M engine, the socket that the bootstrap procedure was run on is already closed, so there is no active DTLS session.

    From what I've seen in the LWM2M implementation, the LWM2M engine will store the DTLS credentials received in the object instance stored in RAM (during the bootstrap procedure). As already pointed out, we should not try to store the credentials in the modem at this point (we can register `post_write_cb` callback), as it will break the bootstrapping procedure. I see two ways how we could tackle this problem:

    1. When the bootstrap server finishes the bootstrap procedure, we get `LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE` event in the application. At this point, the connection with the bootstrap server is done, and we have not started the connection with the actual LWM2M server. It should be safe to put the link down at this point, read the credentials from the security object and store them in the modem,
    2. Implement and register a custom `load_credentials` function as suggested, which is called just before a new socket is created. It will be called after the bootstrap procedure, and before the actual LWM2M server registration. It could be used to store the credentials in the modem as well.

    Of course, I cannot guarantee that there is no not-yet-discovered bug in the LWM2M implementation as unfortunately, even the upstream sample does not show how to combine DTLS + bootstrapping.

    Best regards,

    Didrik

  • Thanks a lot Didrik,

    I will review the proposed solution again, I might have misunderstood the dynamics of the LwM2M client. I get back to you.

    BR / Björn

  • Let me know what you find out. It is valuable feedback to our developers.

Related