This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BOOSTXL-CC3135: TLS Client Auth DECRYPT_ERROR

Part Number: BOOSTXL-CC3135
Other Parts Discussed in Thread: UNIFLASH, CC31XXEMUBOOST, CC3135

I'm using the BOOSTXL board as an external network processor to my main (ST) dev kit. My embedded system is a WebSocket client and connects to my WebSocket server (Python) via the BOOST WiFi connection. The problem I'm having is that when I enforce 2-way authentication on my server, the TLS Handshake is failing at the CertificateVerify stage. Everything works as expected without two way authentication enabled. I actually have a second embedded system that does work with two-way auth, using the same firmware, the same procedure to generate the cert etc. I've done a spot the difference between the systems and nothing stands out.

To rule out the Python server, I used openssl s_server and this confirms the same failure. My firmware gets an SL_ERROR_BSD_ESEC_DECRYPT_ERROR1 (-351) return code from sl_connect, as expected with this error.

Related details:

  1. I've created my own self-signed CA
  2. My firmware uses the simplelink API to generate the CSR on command
  3. For speed (this is prototype system design atm) this is how I provision the BOOST after generating the CSR:
    1. Using a CC31XXEMUBOOST board and UniFlash I read out the CSR file
    2. sign the CSR using my CA
    3. Take the opportunity to add the latest service pack to the new image to write
    4. Add the signed cert to the new image (\custom\mycert.pem)
    5. Add the CA (\custom\myca.pem)
    6. Flash the BOOST
    7. Command firmware to generate the CSR (again) - this causes the device unique key-pair file to be created on the newly flashed BOOST filesystem
  4. In firmware, before connecting, use setsockopt:
    1. to specify the custom CA file
    2. to specify the custom cert
    3. to specify the default system private key file (/sys/cert/iot/key.der)
    4. to disable the trusted root certificate store (SL_SO_SECURE_DISABLE_CERTIFICATE_STORE)
  5. On firmware boot I print out (ls) the BOOST filesystem and can confirm the presence of the key.der, the custom CA and the cert.
  6. Looking at the debug output from the openssl server when a connection is attempting to be established, the certificate the BOOST sends is a match for the originally created cert on my system. 
  7. I can verify the certificate against my CA using openssl
  8. The server seems to be selecting the cipher suite ECDHE-ECDSA-AES128-SHA256
  9. The embedded cert (on the BOOST) has an EC P256 public key and a signature using SHA256 with RSA
  10. My CA cert public key is 2048-bit RSA, it's signature is SHA256 with RSA
  11. The server cert I pass to openssl has a EC P256 public key, and SHA256 RSA signature (also signed by my CA)
  12. The client and server hello is performed, certs are exchanged, cipher is negotiated, and when the BOOST sends the signed verification signature the server sends the DECRYPT_ERROR alert back.
  13. CC3135 hardware / firmware details:
    1. CHIP ID 823132160
    2. MAC 3.7.0.1
    3. PHY 3.1.0.26
    4. NWP 4.10.0.1
    5. ROM 8738
    6. HOST 3.0.1.71 (from simplelink_cc32xx_sdk_5_10_00_02)

What am I missing here?? 

The only thing I can possibly see is that the comments in the simplelink CSR example suggest only certificate v3 is supported, and my certs are v1 - I'd need to supply some extension info when signing the CSR to make is v3. I suspect that I'd get a certificate error if this was the case, and I always assumed the v3 only support was relating to the self-signed certificate generation on the boost.

Here's some (redacted) details from openssl about the various certs being used:

CA

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
35:75:...
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = GB, ST = .., L = .., O = .., CN = myca, emailAddress = ..
Validity
Not Before: May 19 15:38:13 2021 GMT
Not After : May 17 15:38:13 2031 GMT
Subject: C = GB, ST = .., L = .., O = .., CN = myca, emailAddress = ..
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:b1:df:14:87:24:1b:1a:ed:e5:7b:b7:2f:68:c2:
...
d9:c9:aa:af:c1:69:21:76:ac:29:95:23:df:bc:62:
97:cb
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
3C:...
X509v3 Authority Key Identifier:
keyid:3C:7...

X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
89:35:80:2a:98:ac:8a:2e:0c:00:67:16:3a:41:1c:a6:66:a3:
...
9c:ca:e7:a3

BOOST CSR

Certificate Request:
Data:
Version: 3 (0x2)
Subject: C = GB, ST = .., L = .., SN = .., O = .., OU = .., CN = ..<unique>.., emailAddress = ..
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:90:31:60:b8:1a:05:a7:91:99:c1:b7:af:a6:44:
...
ae:31:4b:66:41
ASN1 OID: prime256v1
NIST CURVE: P-256
Attributes:
a0:00
Signature Algorithm: ecdsa-with-SHA1
30:45:02:21:00:c8:73:b8:84:bb:3a:10:36:76:cd:b0:21:7f:
...
79:c3:28:a6:90:c7:45:1d:a0:e5:60:b9:04:9c:a1:8d:b3

BOOST CERT

Certificate:
Data:
Version: 1 (0x0)
Serial Number:
30:1f...
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = GB, ST = .., L = .., O = .., CN = myca, emailAddress = ..
Validity
Not Before: Jun 16 13:26:59 2021 GMT
Not After : May 23 13:26:59 2121 GMT
Subject: C = GB, ST = .., L = .., SN = .., O = .., OU = .., CN = ..<unique>.., emailAddress = ..
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:90:31:60:b8:1a:05:a7:91:99:c1:b7:af:a6:44:
...
ae:31:4b:66:41
ASN1 OID: prime256v1
NIST CURVE: P-256
Signature Algorithm: sha256WithRSAEncryption
53:b5:3d:b4:5f:d4:73:44:64:31:ed:8b:ff:89:12:e1:69:97:
...
3d:c6:af:19

Server CERT

Certificate:
Data:
Version: 1 (0x0)
Serial Number:
30:1f:84:ce:61:cb:18:5f:e7:6b:9c:70:18:5a:23:dc:5e:58:ee:8d
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = GB, ST = .., L = .., O = .., CN = myca, emailAddress = ..
Validity
Not Before: Jun 4 13:06:02 2021 GMT
Not After : Jun 4 13:06:02 2022 GMT
Subject: C = GB, ST = .., L = .., O = .., OU = .., CN = 192.168.1.91, emailAddress = ..
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:bc:76:b4:6c:84:ba:db:4d:e3:b4:9d:83:2e:28:
...
e4:b3:1b:e5:75
ASN1 OID: prime256v1
NIST CURVE: P-256
Signature Algorithm: sha256WithRSAEncryption
48:12:f7:8f:39:9e:44:cc:37:23:48:92:a8:7a:70:71:a2:fa:
...
db:90:20:7f

OpenSSL Server debug output:

openssl s_server -port 12345 -cert Server\192.168.1.91\192.168.1.91.crt -key Server\192.168.1.91\localDevelopmentServer.key -verifyCAfile "myca\myca.pem" -debug -msg -security_debug_verbose -Verify 2

verify depth is 2, must return a certificate
Using default temp DH parameters
Security callback: Certificate chain EE key=EC, bits=256, security bits=128: yes
Security callback: Certificate chain CA digest=RSA-SHA256, security bits=128: yes
ACCEPT

Security callback: Version=TLS 1.3: yes
Security callback: Version=TLS 1.3: yes
Security callback: Version=TLS 1.2: yes
Security callback: Version=TLS 1.1: yes
Security callback: Version=TLS 1.0: yes

read from 0x6000adf40 [0x6001b3153] (5 bytes => 5 (0x5))
0000 - 16 03 03 00 83 .....
<<< ??? [length 0005]
16 03 03 00 83

read from 0x6000adf40 [0x6001b3158] (131 bytes => 131 (0x83))
0000 - 01 00 00 7f 03 03 99 00-4d 65 e3 19 b9 da 17 ea ........Me......
...
0080 - 01 02 01 ...
<<< TLS 1.3, Handshake [length 0083], ClientHello
01 00 00 7f 03 03 99 00 4d 65 e3 19 b9 da 17 ea
...
01 02 01

Security callback: Version=TLS 1.2: yes
Security callback: Version=TLS 1.3: yes
Security callback: : yes
Security callback: Shared Signature Algorithm scheme=ecdsa_secp521r1_sha512, security bits=256: yes
Security callback: Shared Signature Algorithm scheme=ecdsa_secp384r1_sha384, security bits=192: yes
Security callback: Shared Signature Algorithm scheme=ecdsa_secp256r1_sha256, security bits=128: yes
Security callback: Shared Signature Algorithm scheme=ecdsa_sha1, security bits=80: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha512, security bits=256: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha384, security bits=192: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha256, security bits=128: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha1, security bits=80: yes
Security callback: Shared Signature Algorithm scheme=ecdsa_secp521r1_sha512, security bits=256: yes
Security callback: Shared Signature Algorithm scheme=ecdsa_secp384r1_sha384, security bits=192: yes
Security callback: Shared Signature Algorithm scheme=ecdsa_secp256r1_sha256, security bits=128: yes
Security callback: Shared Signature Algorithm scheme=ecdsa_sha1, security bits=80: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha512, security bits=256: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha384, security bits=192: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha256, security bits=128: yes
Security callback: Shared Signature Algorithm scheme=rsa_pkcs1_sha1, security bits=80: yes
Security callback: Check Curve=P-256, security bits=128: yes
Security callback: Shared Curve=P-256, security bits=128: yes
Security callback: Shared Ciphersuite=ECDHE-ECDSA-AES128-SHA256, security bits=128: yes

>>> ??? [length 0005]
16 03 03 00 4a

>>> TLS 1.2, Handshake [length 004a], ServerHello
02 00 00 46 03 03 15 1a 87 08 5a 9d f9 44 4f 10
...
d2 bc ea 91 95 3d cb c0 23 00
Security callback: Certificate chain EE key=EC, bits=256, security bits=128: yes
Security callback: Certificate chain CA digest=RSA-SHA256, security bits=128: yes
>>> ??? [length 0005]
16 03 03 02 dd

>>> TLS 1.2, Handshake [length 02dd], Certificate
0b 00 02 d9 00 02 d6 00 02 d3 30 82 02 cf 30 82
...
00 1a 8c f7 78 fe aa 80 ad db 90 20 7f
Security callback: Shared Curve=P-256, security bits=128: yes

>>> ??? [length 0005]
16 03 03 00 93

>>> TLS 1.2, Handshake [length 0093], ServerKeyExchange
0c 00 00 8f 03 00 17 41 04 70 8f 93 b3 26 a2 71
...
ef 6f 64
Security callback: Signature Algorithm mask scheme=ecdsa_secp256r1_sha256, security bits=128: yes
Security callback: Signature Algorithm mask scheme=rsa_pss_pss_sha256, security bits=128: yes
Security callback: Signature Algorithm mask digest=SHA224, algorithm=DSA, security bits=112: yes
Security callback: Supported Signature Algorithm scheme=ecdsa_secp256r1_sha256, security bits=128: yes
Security callback: Supported Signature Algorithm scheme=ecdsa_secp384r1_sha384, security bits=192: yes
Security callback: Supported Signature Algorithm scheme=ecdsa_secp521r1_sha512, security bits=256: yes
Security callback: Supported Signature Algorithm scheme=rsa_pss_pss_sha256, security bits=128: yes
Security callback: Supported Signature Algorithm scheme=rsa_pss_pss_sha384, security bits=192: yes
Security callback: Supported Signature Algorithm scheme=rsa_pss_pss_sha512, security bits=256: yes
Security callback: Supported Signature Algorithm scheme=rsa_pss_rsae_sha256, security bits=128: yes
Security callback: Supported Signature Algorithm scheme=rsa_pss_rsae_sha384, security bits=192: yes
Security callback: Supported Signature Algorithm scheme=rsa_pss_rsae_sha512, security bits=256: yes
Security callback: Supported Signature Algorithm scheme=rsa_pkcs1_sha256, security bits=128: yes
Security callback: Supported Signature Algorithm scheme=rsa_pkcs1_sha384, security bits=192: yes
Security callback: Supported Signature Algorithm scheme=rsa_pkcs1_sha512, security bits=256: yes
Security callback: Supported Signature Algorithm digest=SHA224, algorithm=ECDSA, security bits=112: yes
Security callback: Supported Signature Algorithm scheme=ecdsa_sha1, security bits=80: yes
Security callback: Supported Signature Algorithm digest=SHA224, algorithm=RSA, security bits=112: yes
Security callback: Supported Signature Algorithm scheme=rsa_pkcs1_sha1, security bits=80: yes
Security callback: Supported Signature Algorithm digest=SHA224, algorithm=DSA, security bits=112: yes
Security callback: Supported Signature Algorithm digest=SHA1, algorithm=DSA, security bits=80: yes
Security callback: Supported Signature Algorithm digest=SHA256, algorithm=DSA, security bits=128: yes
Security callback: Supported Signature Algorithm digest=SHA384, algorithm=DSA, security bits=192: yes
Security callback: Supported Signature Algorithm digest=SHA512, algorithm=DSA, security bits=256: yes

>>> ??? [length 0005]
16 03 03 00 3a

>>> TLS 1.2, Handshake [length 003a], CertificateRequest
0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 06 03
...
02 02 04 02 05 02 06 02 00 00

>>> ??? [length 0005]
16 03 03 00 04

>>> TLS 1.2, Handshake [length 0004], ServerHelloDone
0e 00 00 00
write to 0x6000adf40 [0x6001bc370] (1041 bytes => 1041 (0x411))
0000 - 16 03 03 00 4a 02 00 00-46 03 03 15 1a 87 08 5a ....J...F......Z
...
0400 - 04 02 05 02 06 02 00 00-16 03 03 00 04 0e 00 00 ................
0410 - 00 .

read from 0x6000adf40 [0x6001b3153] (5 bytes => 5 (0x5))
0000 - 16 03 03 03 08 .....
<<< ??? [length 0005]
16 03 03 03 08

read from 0x6000adf40 [0x6001b3158] (776 bytes => 776 (0x308))
0000 - 0b 00 03 04 00 03 01 00-02 fe 30 82 02 fa 30 82 ..........0...0.
...
0300 - 66 10 16 7a 3d c6 af 19- f..z=...
<<< TLS 1.2, Handshake [length 0308], Certificate
0b 00 03 04 00 03 01 00 02 fe 30 82 02 fa 30 82
...
66 10 16 7a 3d c6 af 19
depth=1 C = GB, ST = .., L = .., O = .., CN = myca, emailAddress = ..
verify return:1
depth=0 C = GB, ST = .., L = .., SN = .., O = .., OU = .., CN = ..<unique>.., emailAddress = ..
verify return:1

read from 0x6000adf40 [0x6001b3153] (5 bytes => 5 (0x5))
0000 - 16 03 03 00 46 ....F
<<< ??? [length 0005]
16 03 03 00 46

read from 0x6000adf40 [0x6001b3158] (70 bytes => 70 (0x46))
0000 - 10 00 00 42 41 04 ad 9d-f5 63 2c 98 a5 50 83 c0 ...BA....c,..P..
...
0040 - e2 35 75 24 a8 57 .5u$.W
<<< TLS 1.2, Handshake [length 0046], ClientKeyExchange
10 00 00 42 41 04 ad 9d f5 63 2c 98 a5 50 83 c0
...
e2 35 75 24 a8 57

read from 0x6000adf40 [0x6001b3153] (5 bytes => 5 (0x5))
0000 - 16 03 03 00 4f ....O
<<< ??? [length 0005]
16 03 03 00 4f

read from 0x6000adf40 [0x6001b3158] (79 bytes => 79 (0x4F))
0000 - 0f 00 00 4b 04 03 00 47-30 45 02 21 00 8c d2 39 ...K...G0E.!...9
...
0040 - f4 03 35 64 b6 91 98 34-98 d6 55 96 54 15 f8 ..5d...4..U.T..
<<< TLS 1.2, Handshake [length 004f], CertificateVerify
0f 00 00 4b 04 03 00 47 30 45 02 21 00 8c d2 39
...
f4 03 35 64 b6 91 98 34 98 d6 55 96 54 15 f8
Security callback: Check Curve=P-256, security bits=128: yes
Security callback: Check Signature Algorithm scheme=ecdsa_secp256r1_sha256, security bits=128: yes

>>> ??? [length 0005]
15 03 03 00 02
write to 0x6000adf40 [0x6001bc370] (7 bytes => 7 (0x7))
0000 - 15 03 03 00 02 02 33 ......3

>>> TLS 1.2, Alert [length 0002], fatal decrypt_error
02 33
ERROR
25769902144:error:1417B07B:SSL routines:tls_process_cert_verify:bad signature:ssl/statem/statem_lib.c:505:
shutting down SSL
CONNECTION CLOSED

  • Hi,

    Please try to capture an NWP log (see details in chapter 20 of the programmer's guide (https://www.ti.com/lit/swru455).

  • I'm using the CC3135BOOST as a network coprocessor, is there another way to enable NWP log without an on-chip application enabling pin 62? Is this already enabled on the BOOST board? If i plug in the EMUBOOST (to attempt connection to the 4th COM port) will this interfere with my firmware's operation of the CC3135 BOOST board (using SPI, nHIB, rst lines)?

  • Looking at P4.7 on the BOOST header now. Hopefully I just need to feed that in or manually wire that to the EMU board (to use it's serial converter)..

  • Hi,

    With CC31xx family of devices you don't need to mux anything on the software (only on CC32xx).

    It does not interfere with any of the real time operations of the firmware as it always goes out.

    Regards,

    Shlomi

  • Thanks, was off by one pin on the EMU board - read the NWP log out via the 4th enumerated COM port / EMU board.

  • /cfs-file/__key/communityserver-discussions-components-files/968/CC3135BOOST_5F00_NWP.log

    Started server, reset my firmware, NWP capture attached. There's probably a little garbage captured at the beginning before I hit reset..

    Thanks.

  • Hi,

    Can you attached the certificates created (the root CA and the client certificate)?

    Shlomi

  • I can't without compromising an existing demo system, and exposing client details.

    • Does the NWP log expose the private key? If so is there any way to send that to me and I can test the client cert against the openssl server, with openssl s_client? (thinking about it - will i be able to read the private key using the EMU board and UniFlash? I imagine that's prevented for security)
    • Is the device private key hard coded? i.e. every time the csr is generated is it the same hard coded key that is copied to the .key file in the file system, or is it generating a new random key every time?
    • I have verified byte for byte that the cert the BOOST sends to the server is identical to the original on my system, which passes the CA verification using openssl verify.

    My gut is telling me it's either the fact that the client cert is an x509v1 or the cipher suite the client and server agree on is not correct.

  • Hi,

    The certificate are not private so I do not see a reason it is compromised.

    NWP does not expose the private key.

    The device key created upon CSR is kept in the device and cannot be fetched for security reasons. There is one unique key and other keys that can change (temporary). I guess you are using the unique key.

    Have you flashed and installed the root CA that should verify the client certificate on the server side?

    Also, in this case an air sniffer may help.

    Shlomi

  • compromise probably wasn't the best word - I'll stick with exposed. Of course without the CA private key no-one can use the CA, but both the CA and the device cert have company and device info baked into them. The client cert is technically private in this scenario - only exposed to the chosen server when establishing a call home. Basically just keeping the client private.

    Correct that I'm using the unique key. 

    I created a new local key with 

    openssl ecparam -out <file>.key -name prime256v1 -genkey

    then a local CSR using that key, and signed it with the same CA i've been using throughout. Then using openssl ran a client demo against the openssl server using the new (x509v1) certificate:

    openssl s_client -connect <ip>:<port> -cert v1test.crt -key p256v1.key -CAfile <myCA> -tls1_2 -cipher ECDHE-ECDSA-AES128-SHA256 -curves prime256v1

    I specified TLS 1.2 and the cipher and curve to exactly match what the BOOST uses when it attempts to connect. The connection succeeds. So I'm ruling out the fact that the x509 being v1 is the issue.

    I would imagine that key or CA specific failures would yield error messages that indicate that. Think I'm going to have to have a go at manually computing the verify hash the client is sending, using the exchanged random values, to see if that gives any clues..
  • I understand. please let me know how your testing goes.