wolfSSL / wolfssl

The wolfSSL library is a small, fast, portable implementation of TLS/SSL for embedded devices to the cloud. wolfSSL supports up to TLS 1.3 and DTLS 1.3!
https://www.wolfssl.com
GNU General Public License v2.0
2.35k stars 831 forks source link

Issues using the ATECC508A/ATECC608A #1793

Closed WolfWalter closed 6 years ago

WolfWalter commented 6 years ago

Hi, I'm trying to use wolfssl in combination with wolfMqtt on a PIC32MZ2064DAH and the ATECC508A/ATECC608A. I had multiple issues but finally everything compiles and runs, but I get an Alert ("bad record mac") in the wolfssl debug output and Wireshark log. The same code without "WOLFSSL_ATECC508A" works as expected. I had to add

 #ifdef WOLFSSL_ATECC508A
    /* populate key->pubkey_raw */
    XMEMCPY(key->pubkey_raw, (byte*)in, sizeof(key->pubkey_raw));
#endif

after

/* adjust to skip first byte */
    inLen -= 1;
    in += 1;

in wc_ecc_import_x963_ex() (ecc.c). Otherwise the pubkey_raw buffer for EccSharedSecret() was empty.

If I add the callbacks as suggested in the atmel README.md the TLS-connection fails with BAD_COND_E. The corresponding code is commented with:

/ TODO: Implement equiv call to ATECC508A /

A forums post from 2017 suggest that the implementation is not finished?

Should this use-case be possible with wolfssl? I tried 3.15.3 and the current master version.

dgarske commented 6 years ago

Hi WolfWalter,

Thanks for your excellent question and issue report. As you've noticed there is some work for the ATECC508A, which hasn't been fully implemented. I will take a look at your report about populating pubkey_raw in wc_ecc_import_x963_ex.

Currently we support using the ATECC508A for TLS via our HAVE_PK_CALLBACKS option (./configure --enable-pkcallbacks).

You can find details for using this here: https://github.com/wolfSSL/wolfssl/tree/master/wolfcrypt/src/port/atmel

If you have the PK callbacks option defined at build time and you are setting the wolfSSL_CTX_SetEccSharedSecretCb, wolfSSL_CTX_SetEccVerifyCb, wolfSSL_CTX_SetEccSignCb callbacks you should be able to use the ATECC508A with TLS as a client. For the server side you'll need to make sure wolfSSL_CTX_SetEccKeyGenCb is also set.

We have implemented reference PK callbacks for ECC sign, verify and shared secret here: https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/src/port/atmel/atmel.c#L263

The other supported use case is calling our wc_ecc_* fuctions directly with WOLFSSL_ATECC508A defined.

We plan to work on adding support for using the ATECC508A natively (without PK callbacks) for TLS soon.

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi dgarske, thank you for the quick response. I already tried to define WOLFSSL_ATECC508A and HAVE_PK_CALLBACKS. But in atcatls_create_pms_cb() wc_ecc_import_unsigned() (in ecc.c) is called wich is a wrapper for wc_ecc_import_raw_private() (in ecc.c). This function returns BAD_COND_E because of:

#ifdef WOLFSSL_ATECC508A
    /* TODO: Implement equiv call to ATECC508A */
    err = BAD_COND_E;
    (void)d;
    (void)encType;

#else
...

What am I doing wrong here?

With the cited code commented out there are no errors, but still get the alert ("bad record mac").

console_logs.txt

edit 1: I tried another mqtt test sever (test.mosquitto.org instead of iot.eclipse.org) and now it works. Not sure why. My goal is to work with AWS-IOT. Hopefully that will work too. When I use test.mosquitto.org it also works without HAVE_PK_CALLBACKS!

edit 2: That only worked because the TLS-Connection with test.mosquitto.org is using TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d) an no ECDH is involved. :(

dgarske commented 6 years ago

Hi WolfWalter,

To get that scenario to work do not define WOLFSSL_ATECC508A. Then you'll need to handle calling the atcatls_init as is done in wolfcrypt/src/port/atmel/atmel.c:226 in function atmel_init yourself outside of wolfSSL.

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi, the issue persists with WOLFSSL_ATECC508A not defined. Still got the alert. I will try different servers next.

WolfWalter commented 6 years ago

Hi, I tried the wolfMQTT awsiot example and after solving some problems (not related to wolfssl) it works and uses the ATECC508A (ATECC608A works as well). I'm using the WOLFSSL_ATECC508A variant with the "pubkey_raw"-fix (PR 1804). I'm still not sure what the issue with the iot.eclispe.org-MQTT server is. Any ideas?

edit: Additional info for the used cipher suites used in the TLS connections: iot.eclipse.org: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) a2dujmi05ideo2.iot.us-west-2.amazonaws.com: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)

dgarske commented 6 years ago

Hi WolfWalter,

Thanks for your fixes in PR #1804. Have you tried the fix in wolfMQTT (https://github.com/wolfSSL/wolfMQTT/pull/90 that resolves a new issue with packets over 128 bytes in size? That started with the MQTT v5 changes in https://github.com/wolfSSL/wolfMQTT/pull/87

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi, the PR-Version works for the aws-iot example but did not help with the issue at the mqttclient-example and the iot.eclipse.org server.

The current wolfMQTT master did not run on my board. I got a system-exception and was not yet able to track it down.

dgarske commented 6 years ago

Hi WolfWalter,

It would be helpful to get a Wireshark trace and/or wolfSSL logs. Logging can be enabled by defining DEBUG_WOLFSSL and calling wolfSSL_Debugging_ON(). Can you also send us your build options (either your ./configure statement or user_settings.h)? If you'd like to start a support ticket just email us at support@wolfssl.com and reference this GitHub issue.

With iot.eclipse.org it requires RSA enabled. Looks like its using the cipher suite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). Make sure NO_RSA is not defined. If using fast math (USE_FAST_MATH) Make sure FP_MAX_BITS is either not defined or set to maxkeysz * 2 = 4096.

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi, thank you for the support! Here are the requested files for the mqttclient-example (iot.eclipse.org): config.h.txt console_log.txt user_settings.h.txt wireshark_log.zip

NO_RSA is not defined and FP_MAX_BITS is not set.

dgarske commented 6 years ago

Hi WolfWalter,

In your console_log.txt:

received record layer msg                                                       
got ALERT!                                                                      
Got alert                                                                       
wolfSSL error occurred, error = 20   

The alert code 20 is bad_record_mac.

That error along with the PIC32MZ is one I recognize and has been fixed recently. There were a few bugs with the PIC32MZ hashing and crypto hardware acceleration that caused a bad record mac, which have been fixed.

Those fixes are:

Will you confirm you are using a version of wolfSSL that contains these fixes?

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi, I started with v3.15.3 but I have also tried current versions of wolfssl all with the same result (bad record mac). For the logs I used your branch d0c728b.

I solved my issue using the current master of wolfMQTT but still got the same error.

dgarske commented 6 years ago

Hi WolfWalter,

Can you try disabling the PIC32MZ crypto hardware to verify its not related? You'll need to define the following in your config.h or user_settings.h file.

#define NO_PIC32MZ_CRYPT
#define NO_PIC32MZ_HASH

If this resolves the issue then we know its related to the PIC32MZ crypto hardware. Their have been a handful of fixes for PIC32MZ going back father, most of which are in the latest Harmony. Which Harmony version are you using? Also Harmony uses us for the crypto engine and TLS, so there is duplicated code. They are trying to clean that up, but you may end up having to update wolfCrypt sources in framework/crypto/src and third_party/tcpip/wolfssl.

The framework/crypto/src is a combination of the wolfcrypt/src/.c and wolfssl/wolfcrypt/.h including the pic32mz-crypt.c and pic32mz-crypt.h files from wolfcrypt/src/port/pic32 and wolfssl/wolfcrypt/port/pic32/.

The third_party/tcpip/wolfssl is basically a straight copy of the last release.

Let us know the results.

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi, I already had deactivated the PIC32MZ crypto hardware and used the current wolfssl sources. Harmony-Version is 2.06. For now I'm out of ideas. Hopefully you find the time to integrate the ATECC-chips officially soon.

dgarske commented 6 years ago

Hi @WolfWalter,

We discovered a bug in the ECC shared secret reference callback for the client side case that was not loading the peer key. It would be great if you could test again with the latest in PR #1815 ( https://github.com/wolfSSL/wolfssl/pull/1815/commits/e53694b351f49c93bc8aa4f8b11f2e22f9419bff).

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi @dgarske, the wolfMQTT mqttclient example (using the iot.eclipse.org broker) and the awsiot example are working now, which is fantastic! Thanks for the effort.

But both examples only using the atcatls_create_pms_cb() and not atcatls_verify_signature_cb() and atcatls_sign_certificate_cb(). Sadly I still got issues with these callbacks, trying to use my own certificates stored on the ATECC. I'll try to document these issues in a seperat message.

WolfWalter commented 6 years ago

Hi @dgarske, I provisioned the ATECC with the Microchip-aws-iot-zero-touch-secure-provisioning-kit as documented here and here. I also ported the firmware to the PIC32MZ, which uses the TLS-stack from the WINC1500 wifi-module. That also worked without problems. As a base I used the now working awsiot example and did the following steps to use certificates the provisioned ATECC:

At runtime the atcatls_verify_signature_cb fails with ATCA_CHECKMAC_VERIFY_FAILED in atcab_verify_extern. I added some logging to the atcatls_verify_signature_cb function directly before the atmel_ecc_verify call. ws.zip console.txt

The AWS-server sends two certificates. The content of sig is identical to the signature in the TLS-"server key exchange" in wireshark for both verifications. The peerKey is the same as in the public key for each certficate. I guess I have to study the TLS-standard and the wolfssl documentation to get a better understanding if this is correct. Maybe you could give some clarification?

When I comment the hardware verification out and use wc_ecc_make_key_ex the atcatls_sign_certificate_cb leads to an TLS "Bad Certificate" alert.

dgarske commented 6 years ago

Hi @WolfWalter,

You might have success with some recent fixes in PR #1885 here: https://github.com/wolfSSL/wolfssl/pull/1885

It resolves a few issues around using PK callbacks, key size selection and hash algorithms. Let me know if that resolves any of the issues you are seeing.

Thanks, David Garske, wolfSSL

WolfWalter commented 6 years ago

Hi @dgarske, with this PR the used signature for the second certificate changes, but it does not resolve the issue: console2.txt ws2.zip

WolfWalter commented 6 years ago

Hi @dgarske, I think I found the issue! sigRs is excpected to be 64 Byte by atmel_ecc_sign and atmel_ecc_verify but was 128 Byte. My use case now works 100%. I submitted a PR.

Thanks again for the support.