PolarSSL is now part of ARM Official announcement and rebranded as mbed TLS.

mbedtls_ssl_read( ssl, ReadBuf, 16 ) error bad_record_mac(20) Why?


Mar 21, 2018 09:13
Dmitrii

Fist I send information block to server:

    if(mbedtls_ssl_write(&ssl, MQTTSendStr, sizeof(TLSSendStr)) <= 0)
                {
                    ret = ssl_write_failed;
                }

And I see RET = 0. That mean OK. mbedtls_ssl_write perfoms all handshake procidure and send my message. Then I see that server send me the packet: +IPD,31. 31byte. And I try to read it. I see that ssl.in_msglen = 16. And I try to read 16byte:

    ret = mbedtls_ssl_read( &ssl, ReadBuf, 16 );

But message is fatal error - bad_record_mac(20). Why I recieve bad_record_mac error? Part of Log is bellow:

=> read record
=> fetch input

in_left: 0, nb_want: 5
<= fetch input
input record header

15 03 03 00 1a 
input record: msgtype = 21, version = [3:3], msglen = 26
=> fetch input

in_left: 5, nb_want: 31
<= fetch input
input record from network

15 03 03 00 1a 67 e0 12 7b c5 6f ec 7b f5 5e cd 
c6 1e 55 f0 36 58 af 53 e7 98 36 1e 95 24 fc 
=> decrypt buf
additional data used for AEAD

00 00 00 00 00 00 00 01 15 03 03 00 02 
IV used

07 59 57 9a 67 e0 12 7b c5 6f ec 7b 
TAG used

cd c6 1e 55 f0 36 58 af 53 e7 98 36 1e 95 24 fc 
raw buffer after decryption

02 14 
<= decrypt buf
input payload after decrypt

02 14 
got an alert message, type: [2:20]
is a fatal alert message (msg 20)
mbedtls_ssl_read_record_layer -30592
mbedtls_ssl_read_record -30592
=> write close notify
=> send alert message
send alert level=1 message=0
=> write record
=> encrypt buf
before encrypt: output payload

01 00 
additional data used for AEAD

00 00 00 00 00 00 00 00 15 03 03 00 02 
IV used

00 00 00 00 00 00 00 00 
before encrypt: msglen = 10, including 0 bytes of padding
after encrypt: tag

59 95 70 31 cb 62 2b 8d b4 0d 18 1b b4 0c 5a 67 
<= encrypt buf
output record: msgtype = 21, version = [3:3], msglen = 26
output record sent to network

15 03 03 00 1a 00 00 00 00 00 00 00 00 0b 00 59 
95 70 31 cb 62 2b 8d b4 0d 18 1b b4 0c 5a 67 
=> flush output
message length: 31, out_left: 31
AT+CIPSEND=31

OK
> 
Recv 31 bytes

SEND OK

<= flush output
<= write record
<= send alert message
<= write close notify
=> free
<= free
 
Mar 22, 2018 05:35
Dmitrii

Earlier I get error got no CA chain error. I set conf->authmode = MBEDTLS_SSL_VERIFY_NONE and problem with got no CA chain disapear. But I not use CA.

Is this problem related to what I wrote above?

 
Mar 22, 2018 08:43
Dmitrii

Probably some wrong in my config?

#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H

/* System support */
#define MBEDTLS_HAVE_ASM

/* mbed TLS feature support */
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_PKCS1_V15

/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_AESNI_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_RSA_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_DHM_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED

#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
#define MBEDTLS_GCM_C
#include "check_config.h"
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
/*
 * Save RAM at the expense of interoperability: do this only if you control
 * both ends of the connection!  (See comments in "mbedtls/ssl.h".)
 * The optimal size here depends on the typical size of records.
 */
//#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
#define MBEDTLS_SSL_MAX_CONTENT_LEN
#define MBEDTLS_DEBUG_C
#endif /* MBEDTLS_CONFIG_H */

Please, help me

 
Mar 25, 2018 13:05
Ron Eldor

Hi Dmitry,
This Fatal alert implies that the derived key is different on both peers, thus causing different MACs to be generated. Therre could be other factors generated different, such as the IV, but the derived key is the most possible explanation.
Please check that MBEDTLS_SSL_MAX_CONTENT_LEN is not too small either. If the message you are receiving is actually longer the what you are reading, then you will not decrepit the full buffer, causing a different result, but this should cause the bad mac error on your side.
This could also imply a memory issue on your platform.
Please refer to:

If you search further in this forum, you will find more similar issues.

Since you are using the unrecommended authmode MBEDTLS_SSL_VERIFY_NONE , it is not guaranteed that the connection is secure, and there could be other issues.
Please set your CA chain, to rule out security potential issues.
Regards,
Mbed TLS Team member
Ron

 
Mar 27, 2018 06:36
Dmitrii

Thank you for the answer.

I see that IV values are different in two ways - in client state: 11 this value is zero.

client state: 11
=> flush output
<= flush output
=> write finished
=> calc  finished tls sha384
finished sha512 state

38 72 2d 31 34 fc fe 8c 03 79 9c 80 82 b0 5a 93 
1c e9 e5 ae c6 a1 26 28 88 17 c3 4c 4e bb 6c e9 
bb f9 1e bc 5b 59 eb 57 b9 68 a9 b8 29 4a 5f 3e 
ea c1 c0 38 d7 c4 15 1c a5 da f0 12 02 98 38 48 
calc finished result

37 df af f1 ac 80 5b 6e 6e 0a bb 5c 
<= calc  finished
switching to new transform spec for outbound data
=> write record
=> encrypt buf
before encrypt: output payload

14 00 00 0c 37 df af f1 ac 80 5b 6e 6e 0a bb 5c 
additional data used for AEAD

00 00 00 00 00 00 00 00 16 03 03 00 10
IV used

00 00 00 00 00 00 00 00 
before encrypt: msglen = 24, including 0 bytes of padding
after encrypt: tag

62 8d 4e b7 51 f7 4e 73 54 c4 be 1c ff 92 e2 87 
<= encrypt buf

In client state: 13 this value is not zero:

client state: 13
=> flush output

<= flush output
=> parse finished
=> calc  finished tls sha384
finished sha512 state

38 72 2d 31 34 fc fe 8c 03 79 9c 80 82 b0 5a 93 
1c e9 e5 ae c6 a1 26 28 88 17 c3 4c 4e bb 6c e9 
bb f9 1e bc 5b 59 eb 57 b9 68 a9 b8 29 4a 5f 3e 
ea c1 c0 38 d7 c4 15 1c a5 da f0 12 02 98 38 48 
calc finished result

2d a3 8e 90 4f 30 82 dd 7d 96 60 3b 
<= calc  finished
=> read record
=> fetch input

in_left: 0, nb_want: 5
<= fetch input
input record header

16 03 03 00 28 
input record: msgtype = 22, version = [3:3], msglen = 40
=> fetch input

in_left: 5, nb_want: 45
<= fetch input
input record from network

16 03 03 00 28 7c 4c d1 e4 eb 7b 89 31 fc e2 ec 
6a 89 00 41 9d 72 d0 e8 a6 ed 79 ab cd f4 54 23 
01 ec fe ad 3a 42 f3 b8 ae 50 83 64 22 
=> decrypt buf
additional data used for AEAD

00 00 00 00 00 00 00 00 16 03 03 00 10 
IV used

48 54 55 4f 7c 4c d1 e4 eb 7b 89 31 
TAG used

f4 54 23 01 ec fe ad 3a 42 f3 b8 ae 50 83 64 22 
raw buffer after decryption

14 00 00 0c 2d a3 8e 90 4f 30 82 dd 7d 96 60 3b 
<= decrypt buf
input payload after decrypt

14 00 00 0c 2d a3 8e 90 4f 30 82 dd 7d 96 60 3b 
handshake message: msglen = 16, type = 20, hslen = 16
<= read record
<= parse finished

From Your post, I realized that the length is different is not a bug:

"As for the wrong IV length, it's only a matter of different log in the encrypt and decrypt of the payload." But the keys are different in value.

Could this be the cause of BAD MAC?

 
Mar 27, 2018 07:25
Ron Eldor

Hi Dmitri,
The IV for in messages and IV for out messages are different, so it doesn't necessary mean reason for bad mac message.
Regards,
Mbed TLS Team member
Ron

 
Mar 27, 2018 14:34
Ron Eldor

Hi Dmitri,
I have just noticed in your configuration file that you have MBEDTLS_SSL_MAX_CONTENT_LEN defined, but no value there. What is the value of your MBEDTLS_SSL_MAX_CONTENT_LEN ?
If the server you are working with is sending a larger packet, it makes sense that you will fail on your decryption, with a bad_mac.
Regards,
Mbed TLS Team member
Ron

 
Mar 27, 2018 15:31
Dmitrii

I have string #define MBEDTLS_SSL_MAX_CONTENT_LEN 13000 in config.h file.

I check several value there:

mpi_mul_hlp(n, N-p, u1) Hang UP