eclipse / tinydtls

Eclipse tinydtls
https://projects.eclipse.org/projects/iot.tinydtls
Other
103 stars 57 forks source link

Experiencing an extended handshake duration on a SAMR21-xpro device. #224

Open LizzieDE110 opened 6 months ago

LizzieDE110 commented 6 months ago

Hello, I am currently working on a project to secure wireless UDP/IP communication between SAMR21-xpro devices using RIOT OS. After some research, I found that using DTLS (with ECDSA keys) was the best solution. Moreover, RIOT has examples that use tinyDTLS.

My problem is that, with SAMR21-xpro, the handshake is extremely long. From the logs and packet analysis, I feel like the problem lies in the key management (generation, signature, and verification). According to tinydtls/ecc/ecc.h, this implementation is supposed to be very efficient for 32-bit CPUs.

I made a quick example on RIOT that just generates a key pair and signs a hashed data. The generation takes ~6 seconds, and the signature also takes 6 seconds. I haven't tested verification, but I assume it also takes many seconds. I am quite confused because initially, when I was trying to run a sock-dtls example from RIOT, I found it would be better to generate a key pair to use, and to do so, I used the micro-ecc library. On SAMR21-xpro, key generation, signature, and verification take barely a second.

Is it normal that the key management is so long on a 32-bit CPU?

Also, I was wondering if it could be a good idea to replace the library used to manage ECC in tinyDTLS with micro-ecc? Or maybe add a patch that could let the user choose what they want to use?

Thanks in advance

boaks commented 6 months ago

From the datasheets of the SAMR21 I found, that it's a Cortex M0+ with 48MHz. Several seconds on a Cortex-M33 (without using the ECC HW accelerator, for now not supported) is also my experience. Depending on quite a lot of other topics, using special HW as a ATECC608 would help, but it's also for now not support.

Also, I was wondering if it could be a good idea to replace the library used to manage ECC in tinyDTLS with micro-ecc?

Do you have some benchmark numbers?

LizzieDE110 commented 6 months ago

What types of benchmark numbers are you interested in? (I'm relatively new to programming, so I'm not very familiar with these processes.)

boaks commented 6 months ago

Pretty simple numbers.

The generation takes ~6 seconds, and the signature also takes 6 seconds. I haven't tested verification, but I assume it also takes many seconds.

Just some number as that. My point is, if it is really faster, e.g. 3s vs. 6s it may be worth. But to be frank, I consider to spend rather time in the ATECC608, because that brings also a "secure store" for key and a real performance boost.

LizzieDE110 commented 6 months ago

Example using ecc from tinydtls/ecc:

2024-02-08 11:34:16,670 # DTLS sock example to generate key and see if it takes a long time
2024-02-08 11:34:23,755 # Keys generated
2024-02-08 11:34:30,593 # Signature created

Similar example using micro-ecc:

2024-02-08 11:32:39,924 # ECDSA key generation example
2024-02-08 11:32:40,336 # Keys generated
2024-02-08 11:32:40,773 # Signature created

I do agree that it would be better to focus on secure element integration. I am working on SAMR21-xpro for a POC, but my final board has an ATECC608A. I have already created some examples using CryptoAuthLib to generate key pairs, sign, and verify signatures, but I felt that it was less user-friendly than micro-ecc.

boaks commented 6 months ago

That's quite fast.

boaks commented 6 months ago

@obgm

Did you already have a look at that alternative ECC implementation?

obgm commented 6 months ago

Also, I was wondering if it could be a good idea to replace the library used to manage ECC in tinyDTLS with micro-ecc?

Yes, definitely. micro-ecc has been evaluated for use with tinydtls a long time ago and also has been used with very good results in other projects as replacement.

LizzieDE110 commented 6 months ago

@obgm I'm interested in seeing the results. Is there a fork of projects that use micro-ecc?

@boaks, do you plan to work on integrating support for a secure element like ATECC608?

I'm working with RIOT OS on my project, and it would be great to integrate both: tinydtls with micro-ecc and tinydtls with ATECC608. With some help, I could do it?

boaks commented 6 months ago

With some help, I could do it?

That will be welcome. Please read CONTRIBUTING.

One point ahead, because I know, that quite a lot are "frustrated" by the "speed" the things get integrated into "main", it will be mainly in "develop" for the near future. If you have a look at the open PRs, it takes quite long until we are up to date with them.

With some help

I will do my best. I'm in vacation from 13.2. to 24.2., beside of that, feel free to open issues, or, if you prefer, send e-mails. I prefer issues, that will also help others with similar topics.

do you plan to work on integrating support for a secure element like ATECC608?

Unfortunately, I have too many plans ;-). I mainly work on Zephyr - Coaps Demo Client with Eclipse/TinyDtls and Californium (Cf) - Cloud CoAP-S3-Proxy Server. Beside of that, I ramp down my time invested in the base projects (tinydtls and californium) to about 4h freetime a week. So, yes I plan to support the ATECC608 now for 5 years but I still haven't started ;-).

obgm commented 6 months ago

Could you please check if PR #228 works for you?

LizzieDE110 commented 6 months ago

Thanks, I have made some reviews.

Currently, I have started implementing a version that could support micro-ecc (and it seems to work), as well as a version that supports cryptoauthlib (to utilise a secure element such as ATECC608A).

However, there are certain aspects that I still don't understand fully. One of them is the ECDH key exchange. I noticed that the pre_master_secret is calculated using the crypto API (micro_ecc or cryptoauthlib). But how is the extended master secret calculated? Why not call the crypto API to calculate a secret using the received one and our secret?

LizzieDE110 commented 6 months ago

Hello! I have discovered the issue myself during the handshake using Cryptoauthlib and ATECC608A. Now, the handshake is completed in less than a second! My work is on a fork here: https://github.com/LizzieDE110/tinydtls/tree/micro-ecc, and I would appreciate your opinion or review, @boaks. (Perhaps I should open a PR?)

I haven't added any documentation yet, but I can explain my point of view briefly: To avoid breaking anything, I have added environment variables like DTLS_MICRO_ECC or DTLS_ATECC608A to allow users to choose which crypto API they would like to use. Then, I have maintained the interface of the crypto API and simply added '#ifdef' to call either ecc, micro-ecc, or cryptoauthlib.

Thanks in advance

boaks commented 6 months ago

I will have a look at it next week when I'm back from vacation.

boaks commented 6 months ago

I've started with PR #228 to work on this ECC performance improvement.

Using zephyr-coaps-client - Cortex-M33/software with the proposed micro-ecc speeds up from 15s with the old ECC implementation to 1. 2s with micro-ecc. That verifies the results from above and is very impressive.

I will compare the work in https://github.com/LizzieDE110/tinydtls/tree/micro-ecc with the one in PR #228, hopefully later this day. (And the ATECC608 stuff next week.)

boaks commented 6 months ago

According https://github.com/LizzieDE110/tinydtls/tree/micro-ecc.

The idea of ECDHE (the last E is for "ephemeral") is using a temporary key pair. With that, the generated secret keys are PFS. Even if the long term (authentication keys) gets disclosed, no one can decrypt recorded sessions, because the generate secrets are based on that ephemeral/temporary key pair.

micro-ecc:

Using a "unsecure random function" opens an side channel attack, because the generated ephemeral key-pair may get reconstructed. Therefore it's recommended to set "uECC_set_rng" with an implementation using "dtls_prng". For example, see PR 288.

cryptoauthlib:

#define ATECC_ECDSA_KEY_ID 2
#define ATECC_ECDH_KEY_ID 2

I'm not common with the HSM for now. I will need to read the details in the docu. So, not sure, if this really applies: Using the long term authentication key-pair for ECDHE, the generated secret keys are not longer PFS. It's somehow "in between" because using a HSM should make it impossible, that the authentication key-pair gets disclosed. Anyway, the other peer may detect the reuse of the same public key in ECDHE and that may cause the handshake to abort.

LizzieDE110 commented 6 months ago

Thank you for the review. I will revise the micro-ecc version according to the feedback you provided in the review of PR 288.

Regarding cryptoauthlib, to perform certain operations such as new key generation, ECDH operation, signature, and verification, the HSM must be configured correctly. In my configuration, cryptographic operations were functional using the 2nd slot (hence the #define).

I refrained from making significant changes to the dtls.c file. Consequently, I didn't alter the function interface to accept slot key ID instead of a private key buffer. I'm uncertain about the best approach between setting the slot key ID at the beginning (using accessors and static variables) or modifying the library to use slot key ID.

What would you suggest?

boaks commented 6 months ago

What would you suggest?

I need to examine it. But to be frank: I don't have the time for now. I consumed all the time I'm able to spend in open source this month the last two days. So it will take a while ...