Topic: wolfSSL TM4C129E support, GCM/GMAC broken

I am trying to use wolfSSL with a TI TM4C129E, for which there is a port provided with wolfSSL to enable the hardware encryption of the chip. My end goal is to act as an HTTPS server, but for now I am just using example code from TI to connect as client. This fails, with a TLS alert "bac_record_mac." I guess the server is rejecting the MAC that the client sends during or shortly after the Client Hello.

I managed (with some effort) to compile and run "wolfcrypt/test/test.c", which succeeds for all tests when hardware encryption is not enabled, and fails for GMAC and AES-GCM when hardware encryption is enabled. I can tell that this test code is not executed for this platform very frequently, if ever, because it did not work at all until I modified the code in "port/ti-*". Most of the modifications were related to querying the keysize after it was set, copying a hash, etc. When it fails on the GMAC and GCM tests though, it's because it got a different answer from the expected result of the test vectors.

What is the status of support for this hardware? Has it been tested recently? I've been reading up on GCM mode from some NIST documents, but I am still confused about what the difference between GMAC and GCM actually is. Is GMAC just a specific use of GCM?

Share

Re: wolfSSL TM4C129E support, GCM/GMAC broken

For clarity, enabling "hardware encryption" for this platform consists of adding these preprocessor defines to the build:
WOLFSSL_TI_HASH
WOLFSSL_TI_CRYPT
TARGET_IS_SNOWFLAKE_RA2
WOLFSSL_TIRTOS

Share

Re: wolfSSL TM4C129E support, GCM/GMAC broken

Hello jbquick,

Thanks for contacting wolfSSL Support. I have requested a review of this from a colleague.

Re: wolfSSL TM4C129E support, GCM/GMAC broken

incremental progress...
I noticed when IV was generated randomly, in AesAuthSetIv(), nonce would be equal to aes->reg, so clearing reg before copying it would clobber the IV that was about to be set.

so in AesAuthSetIv() in ti-aes.c..
I changed

XMEMSET(aes->reg, 0, AES_BLOCK_SIZE)

to...

if(len < 12)
    XMEMSET(aes->reg+len, 0, AES_BLOCK_SIZE-len);

Note that the IF was necessary, otherwise it would fault when IV was larger than 12.. I don't know what the correct thing to do is when IV is larger than 12.. im guessing that simply truncating it isn't the right answer, though.

Regardless, with this change, the GMAC test passes. But the AES-GCM test fails in the portion of test.c that says  /* test with IV != 12 bytes */

Share

Re: wolfSSL TM4C129E support, GCM/GMAC broken

I am running into the same issue as well just using the httpsget sample from TI.
Below is the debug log from wolfssl for the connection if thats helpful.
The bad record mac comes after the first encrypted handshake message from the client.

For some more context the server is selecting is TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 and I have disabled peer verification in wolfssl for now.

Sending a HTTPS GET request to 'www.example.com:443'
[2] wolfSSL Entering TLSv1_2_client_method_ex
[2] wolfSSL Entering wolfSSL_CTX_new_ex
[2] wolfSSL Entering wolfSSL_Init
[2] wolfSSL Entering wolfCrypt_Init
[2] wolfSSL Entering wolfSSL_CertManagerNew
[3] wolfSSL Leaving wolfSSL_CTX_new_ex, return 0
[2] wolfSSL Entering wolfSSL_CTX_set_verify
[2] wolfSSL Entering wolfSSL_new
[2] wolfSSL Entering ReinitSSL
[2] wolfSSL Entering SetSSL_CTX
[2] wolfSSL Entering wolfSSL_NewSession
[3] wolfSSL Leaving wolfSSL_new, return 0
[2] wolfSSL Entering wolfSSL_set_fd
[2] wolfSSL Entering wolfSSL_set_read_fd
[3] wolfSSL Leaving wolfSSL_set_read_fd, return 1
[2] wolfSSL Entering wolfSSL_set_write_fd
[3] wolfSSL Leaving wolfSSL_set_write_fd, return 1
[2] wolfSSL Entering wolfSSL_send
[2] wolfSSL Entering wolfSSL_write
[1] handshake not complete, trying to finish
[2] wolfSSL Entering wolfSSL_negotiate
[2] wolfSSL Entering wolfSSL_connect
[2] wolfSSL Entering ReinitSSL
[2] wolfSSL Entering SendClientHello
[1] Adding signature algorithms extension
[1] growing output buffer
[1] Signature Algorithms extension to write
[1] Point Formats extension to write
[1] Supported Groups extension to write
[1] Shrinking output buffer
[3] wolfSSL Leaving SendClientHello, return 0
[1] connect state: CLIENT_HELLO_SENT
[1] growing input buffer
[1] received record layer msg
[1] got HANDSHAKE
[2] wolfSSL Entering DoHandShakeMsg
[2] wolfSSL Entering DoHandShakeMsgType
[1] processing server hello
[2] wolfSSL Entering DoServerHello
[1] Point Formats extension received
[2] wolfSSL Entering wolfSSL_get_options
[2] wolfSSL Entering VerifyClientSuite
[3] wolfSSL Leaving DoServerHello, return 0
[3] wolfSSL Leaving DoHandShakeMsgType(), return 0
[3] wolfSSL Leaving DoHandShakeMsg(), return 0
[1] Shrinking input buffer
[1] growing input buffer
[1] received record layer msg
[1] got HANDSHAKE
[2] wolfSSL Entering DoHandShakeMsg
[2] wolfSSL Entering DoHandShakeMsgType
[1] processing certificate
[2] wolfSSL Entering DoCertificate
[2] wolfSSL Entering ProcessPeerCerts
[1] Loading peer's cert chain
[1]     Put another cert into chain
[1]     Put another cert into chain
[2] wolfSSL Entering GetExplicitVersion
[2] wolfSSL Entering wc_GetSerialNumber
[1] Got Cert Header
[2] wolfSSL Entering GetObjectId
[1] Got Algo ID
[1] Getting Name
[1] Getting Cert Name
[1] Getting Name
[1] Getting Cert Name
[1] Got Subject Name
[2] wolfSSL Entering GetAlgoId
[2] wolfSSL Entering GetObjectId
[1] Got Key
[1] Parsed Past Key
[2] wolfSSL Entering DecodeCertExtensions
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeBasicCaConstraint
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeSubjKeyId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeAuthKeyId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeKeyUsage
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeExtKeyUsage
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeAuthInfo
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeCrlDist
[2] wolfSSL Entering GetObjectId
[1] Certificate Policy extension not supported yet.
[2] wolfSSL Entering GetObjectId
[1] Chain cert not verified by option, not adding as CA
[1] Verifying Peer's cert
[2] wolfSSL Entering GetExplicitVersion
[2] wolfSSL Entering wc_GetSerialNumber
[1] Got Cert Header
[2] wolfSSL Entering GetObjectId
[1] Got Algo ID
[1] Getting Name
[1] Getting Cert Name
[1] Getting Name
[1] Getting Cert Name
[1] Got Subject Name
[2] wolfSSL Entering GetAlgoId
[2] wolfSSL Entering GetObjectId
[1] Got Key
[1] Parsed Past Key
[2] wolfSSL Entering DecodeCertExtensions
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeAuthKeyId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeSubjKeyId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeAltNames
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeKeyUsage
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeExtKeyUsage
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeCrlDist
[1]     There are more CRL Distribution Point records, but we only use the first one.
[2] wolfSSL Entering GetObjectId
[1] Certificate Policy extension not supported yet.
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeAuthInfo
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering DecodeBasicCaConstraint
[2] wolfSSL Entering GetObjectId
[2] wolfSSL Entering GetObjectId
[1] Verified Peer's cert
[3] wolfSSL Leaving ProcessPeerCerts, return 0
[3] wolfSSL Leaving DoCertificate, return 0
[3] wolfSSL Leaving DoHandShakeMsgType(), return 0
[3] wolfSSL Leaving DoHandShakeMsg(), return 0
[1] Shrinking input buffer
[1] growing input buffer
[1] received record layer msg
[1] got HANDSHAKE
[2] wolfSSL Entering DoHandShakeMsg
[2] wolfSSL Entering DoHandShakeMsgType
[1] processing server key exchange
[2] wolfSSL Entering DoServerKeyExchange
[2] wolfSSL Entering RsaVerify
[3] wolfSSL Leaving RsaVerify, return 51
[3] wolfSSL Leaving DoServerKeyExchange, return 0
[3] wolfSSL Leaving DoHandShakeMsgType(), return 0
[3] wolfSSL Leaving DoHandShakeMsg(), return 0
[1] Shrinking input buffer
[1] received record layer msg
[1] got HANDSHAKE
[2] wolfSSL Entering DoHandShakeMsg
[2] wolfSSL Entering DoHandShakeMsgType
[1] processing server hello done
[3] wolfSSL Leaving DoHandShakeMsgType(), return 0
[3] wolfSSL Leaving DoHandShakeMsg(), return 0
[1] connect state: HELLO_AGAIN
[1] connect state: HELLO_AGAIN_REPLY
[1] connect state: FIRST_REPLY_DONE
[1] connect state: FIRST_REPLY_FIRST
[2] wolfSSL Entering SendClientKeyExchange
[2] wolfSSL Entering EccMakeKey
[3] wolfSSL Leaving EccMakeKey, return 0
[2] wolfSSL Entering EccSharedSecret
[3] wolfSSL Leaving EccSharedSecret, return 0
[1] growing output buffer
[1] Shrinking output buffer
[3] wolfSSL Leaving SendClientKeyExchange, return 0
[1] sent: client key exchange
[1] connect state: FIRST_REPLY_SECOND
[1] connect state: FIRST_REPLY_THIRD
[1] growing output buffer
[1] Shrinking output buffer
[1] sent: change cipher spec
[1] connect state: FIRST_REPLY_FOURTH
[2] wolfSSL Entering SendFinished
[1] growing output buffer
[2] wolfSSL Entering BuildMessage
[3] wolfSSL Leaving BuildMessage, return 0
[2] wolfSSL Entering SetupSession
[2] wolfSSL Entering AddSession
[2] wolfSSL Entering AddSessionToCache
[2] wolfSSL Entering ClientSessionToSession
[2] wolfSSL Entering ClientSessionToSession
[2] wolfSSL Entering ClientSessionToSession
[1] Trying to add client cache entry
[1] Adding client cache entry
[1] Shrinking output buffer
[3] wolfSSL Leaving SendFinished, return 0
[1] sent: finished
[1] connect state: FINISHED_DONE
[1] received record layer msg
[1] got ALERT!
[1] Alert type: bad_record_mac
[0] wolfSSL error occurred, error = 20
[0] wolfSSL error occurred, error = -313
[3] wolfSSL Leaving wolfSSL_negotiate, return -1
[3] wolfSSL Leaving wolfSSL_write, return -1
[3] wolfSSL Leaving wolfSSL_send, return -1
[2] wolfSSL Entering wolfSSL_get_error
[3] wolfSSL Leaving wolfSSL_get_error, return -313
Error! code = -103, desc = httpsTask: send failed

Share

Re: wolfSSL TM4C129E support, GCM/GMAC broken

For now, I found that I can disable GCM by undefining HAVE_AESGCM in settings.h. This allows the connection to be established successfully using CBC mode instead of GCM mode. Although this allows me to continue development, it feels like a temporary solution that still needs proper resolution.

What I don't know is what is the ramification removing GCM support? What cipher suites are required to be supported, or are typically supported by other TLS client/servers? Based on the fact that GCM was chosen when both CBC and GCM are enabled, I interpret that to mean that GCM is the better choice, but I don't really know.

Share

Re: wolfSSL TM4C129E support, GCM/GMAC broken

Hi Ethan and John,

Thank you both for the report of the TM4C issues with AES GCM. I've got a TM4C129XL board here and will see if I can reproduce and fix. Hopefully this board has the AES GCM feature (enabled with `WOLFSSL_TI_CRYPT`).

It sounds like the ti-aes.c isn't properly handling the IV.

Thanks,
David Garske, wolfSSL

Share

Re: wolfSSL TM4C129E support, GCM/GMAC broken

Hi Ethan and John,

Its difficult getting the environment setup. Would one of you mind sharing a CCS project with me?

I've got wolfSSL building using the instructions at https://www.wolfssl.com/documentation/U … -RTOS.pdf, but having trouble importing the TLS echo example. I may just end up creating a simple wolfCrypt_test project from scratch.

So far I've pushed my cleanups to: https://github.com/dgarske/wolfssl/tree/ti_aes , however no real fixes in AES GCM yet.

Feel free to email support at wolfssl dot come directly with any examples and reference this forum link.

Thanks,
David Garske, wolfSSL

Share

Re: wolfSSL TM4C129E support, GCM/GMAC broken

Hi David,
Thank you for looking into this. Sorry for the slow response on my end. I attached the sample project I've been using but its setup for the TM4C129EXL so it may not be super useful. I have my whole environment setup in a VM I could package up for you if that would be helpful.

Share