UtilitechAS / amsreader-firmware

ESP8266 and ESP32 compatible firmware to read, interpret and publish data to MQTT from smart electrical meters, both DLMS and DSMR is supported
Other
386 stars 73 forks source link

ESP32 decryption failed (mbed lib) #248

Closed tyler123durden closed 2 years ago

tyler123durden commented 2 years ago

Describe the bug Decryption of payload fails on ESP32 devices with error HDLC_ENCRYPTION_DECRYPT_FAILED. Same release with ESP8266 works but of course ESP doesn't use mbed enryption library. Decrypted payload looks perfectly fine one both platforms.

Unfortunately I'm not able to set up the development environment to fix this issue, I get errors compiling code but maybe my platformIO setup is screwed up because it complains about not finding xtensa compiler.

            success = mbedtls_gcm_auth_decrypt(&m_ctx, sizeof(cipher_text), config->initialization_vector, sizeof(config->initialization_vector),
                config->additional_authenticated_data, aadlen, config->authentication_tag, authkeylen,
                cipher_text, (unsigned char*)(ptr));
            if (authkeylen > 0 && success == MBEDTLS_ERR_GCM_AUTH_FAILED) {
                return HDLC_ENCRYPTION_AUTH_FAILED;
            } else if(success == MBEDTLS_ERR_GCM_BAD_INPUT) {
                return HDLC_ENCRYPTION_DECRYPT_FAILED;        // <<<<<<--------- error here
            }

Erroneous ESP32 log:

(I) (readHanPort)(C1) Intermediate segment
(D) (readHanPort)(C1) Frame dump (263b):
(D) 68 01 01 68  53 FF 00 01  67 DB 08 53  41 47 59 05 

(D) EA 7A 8E 81  F8 20 00 00  3B FB 4E 9D  51 05 9B 50 

(D) 51 88 1C 69  DE 0B AE A9  B3 A1 18 91  90 05 2D 43 

(D) 34 51 7E 45  33 B2 04 C7  B2 B8 0F 5C  5B 28 C4 89 

(D) 43 86 8E C4  89 13 1F A0  11 9D FB BB  9A DC 05 43 

(D) FE 69 3A 0E  76 8B 96 0F  0F F3 E9 E4  30 76 FA 46 

(D) 43 A1 55 8B  7C 04 7F CD  D6 70 E4 2C  E4 87 E7 81 

(D) 74 D1 85 8A  D2 10 28 EE  BE DF 59 15  3E 62 DC 26 

(D) 9C 3B FD D3  23 B3 1D CB  16 A6 7A CE  50 02 98 45 

(D) 95 1F A4 A8  05 1A D1 D7  20 C2 CC 62  48 DD EC C0 

(D) C2 02 C8 DA  97 01 84 22  ED 1B D3 89  26 E3 32 E4 

(D) A5 94 1E A0  2F BE 9A C2  72 D9 22 BD  C2 D3 BC D9 

(D) 5B 70 7D AE  17 41 5D 34  60 25 AF 9F  48 F3 6E 66 

(D) 69 7D C8 E4  E1 79 55 6E  78 16 E0 ED  46 6D 5D 33 

(D) B3 64 1F 75  02 1F 7A CE  21 B4 93 4D  7D 88 24 5C 

(D) 4E D9 99 04  63 98 FC 86  0C 0D 03 6C  99 02 CD 33 

(D) D6 DD D6 BE  C1 17 16 

(I) (readHanPort)(C1) Final segment
(D) (readHanPort)(C1) Frame dump (19b):
(D) 68 0D 0D 68  53 FF 11 01  67 E0 63 67  8E A2 6E 7B 

(D) 5B E9 16 

(D) (readHanPort)(C1) Frame dump (271b):
(D) 68 00 00 68  53 FF 10 01  67 DB 08 53  41 47 59 05 

(D) EA 7A 8E 81  F8 20 00 00  3B FB 0F 80  0B E2 E3 0C 

(D) 07 E6 03 11  04 0D 35 23  00 FF C4 02  02 23 09 0C 

(D) 07 E6 03 11  04 0D 35 23  00 FF C4 02  09 06 01 00 

(D) 01 08 00 FF  06 00 05 3B  56 02 02 0F  00 16 1E 09 

(D) 06 01 00 02  08 00 FF 06  00 00 2B E7  02 02 0F 00 

(D) 16 1E 09 06  01 00 01 07  00 FF 06 00  00 00 B6 02 

(D) 02 0F 00 16  1B 09 06 01  00 02 07 00  FF 06 00 00 

(D) 00 00 02 02  0F 00 16 1B  09 06 01 00  20 07 00 FF 

(D) 12 09 2A 02  02 0F FF 16  23 09 06 01  00 34 07 00 

(D) FF 12 09 39  02 02 0F FF  16 23 09 06  01 00 48 07 

(D) 00 FF 12 09  32 02 02 0F  FF 16 23 09  06 01 00 1F 

(D) 07 00 FF 12  00 1E 02 02  0F FE 16 21  09 06 01 00 

(D) 33 07 00 FF  12 00 02 02  02 0F FE 16  21 09 06 01 

(D) 00 47 07 00  FF 12 00 53  02 02 0F FE  16 21 09 06 

(D) 01 00 0D 07  00 FF 10 03  6A 02 02 0F  FD 16 FF 09 

(D) 0C 31 37 38  32 31 30 32  35 32 38 37  38 45 16 

(D) (readHanPort)(C1) System title:
(D) 53 41 47 59  05 EA 7A 8E  

(D) (readHanPort)(C1) Initialization vector:
(D) 53 41 47 59  05 EA 7A 8E  00 00 3B FB  

(D) (readHanPort)(C1) Additional authenticated data:
(D) 20 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 

(D) 00 

(D) (readHanPort)(C1) Authentication tag:
(D) 00 00 00 00  00 00 00 00  00 00 00 00  

(W) (readHanPort)(C1) Decryption failed
(D) (AmsWebServer)Serving /data.json over http...
(D) (loop)(C1) Used 0 ms to update temperature
(I) (readHanPort)(C1) Intermediate segment
(D) (readHanPort)(C1) Frame dump (263b):
(D) 68 01 01 68  53 FF 00 01  67 DB 08 53  41 47 59 05 

(D) EA 7A 8E 81  F8 20 00 00  3B FC 7C 57  37 12 30 EB 

(D) AE A2 64 8C  0B 4D E2 88  44 A1 EC A3  4E E2 6D 6B 

(D) 7D B5 21 2A  22 94 2D 9F  11 6C 87 95  28 95 B3 3F 

(D) 6B 7E 0B 23  E5 C5 02 B3  27 F9 39 AD  70 30 BD 8D 

(D) 91 B3 6B AB  74 4F 72 C9  B4 FC F9 E7  CA 7D 4D 9A 

(D) 1C CA 17 DB  F0 2E 60 67  76 97 BD F3  77 8F BB 93 

(D) E3 13 97 33  8E CA 84 EE  3A 67 FF 70  9B 44 75 9E 

(D) FC 13 D2 91  6A 32 1F 8C  45 6F 14 08  15 64 E8 60 

(D) 28 DA EC BC  2D 7E D5 68  1E DE 67 1C  6B 4E 24 44 

(D) 2C 4A AE B7  64 C4 39 23  07 F6 59 78  2A 89 5E 39 

(D) CB 6A 09 4E  18 79 5F 73  96 67 9A 5E  E7 C3 97 F6 

(D) 1D 8D AE C8  99 6B BC F1  CB B8 4A 2F  1C B8 EA C5 

(D) 91 73 49 C5  F4 78 F2 3B  72 21 DE CA  3B 6B EA 25 

(D) 1E CC 56 F8  67 2E 43 65  AC 54 2A BE  CC EA 20 26 

(D) 79 68 90 70  A6 DA 8F EF  DD 87 70 DF  10 17 52 CC 

(D) FE 41 A9 EF  C4 2E 16 

(I) (readHanPort)(C1) Final segment
(D) (readHanPort)(C1) Frame dump (19b):
(D) 68 0D 0D 68  53 FF 11 01  67 27 5F 98  2F 7E 3A 70 

(D) 5B 9B 16 

(D) (readHanPort)(C1) Frame dump (271b):
(D) 68 00 00 68  53 FF 10 01  67 DB 08 53  41 47 59 05 

(D) EA 7A 8E 81  F8 20 00 00  3B FC 0F 80  0B E2 E4 0C 

(D) 07 E6 03 11  04 0D 35 28  00 FF C4 02  02 23 09 0C 

(D) 07 E6 03 11  04 0D 35 28  00 FF C4 02  09 06 01 00 

(D) 01 08 00 FF  06 00 05 3B  56 02 02 0F  00 16 1E 09 

(D) 06 01 00 02  08 00 FF 06  00 00 2B E7  02 02 0F 00 

(D) 16 1E 09 06  01 00 01 07  00 FF 06 00  00 00 B4 02 

(D) 02 0F 00 16  1B 09 06 01  00 02 07 00  FF 06 00 00 

(D) 00 00 02 02  0F 00 16 1B  09 06 01 00  20 07 00 FF 

(D) 12 09 2C 02  02 0F FF 16  23 09 06 01  00 34 07 00 

(D) FF 12 09 39  02 02 0F FF  16 23 09 06  01 00 48 07 

(D) 00 FF 12 09  34 02 02 0F  FF 16 23 09  06 01 00 1F 

(D) 07 00 FF 12  00 1E 02 02  0F FE 16 21  09 06 01 00 

(D) 33 07 00 FF  12 00 02 02  02 0F FE 16  21 09 06 01 

(D) 00 47 07 00  FF 12 00 52  02 02 0F FE  16 21 09 06 

(D) 01 00 0D 07  00 FF 10 03  67 02 02 0F  FD 16 FF 09 

(D) 0C 31 37 38  32 31 30 32  35 32 38 37  38 0E 16 

(D) (readHanPort)(C1) System title:
(D) 53 41 47 59  05 EA 7A 8E  

(D) (readHanPort)(C1) Initialization vector:
(D) 53 41 47 59  05 EA 7A 8E  00 00 3B FC  

(D) (readHanPort)(C1) Additional authenticated data:
(D) 20 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 

(D) 00 

(D) (readHanPort)(C1) Authentication tag:
(D) 00 00 00 00  00 00 00 00  00 00 00 00  

(W) (readHanPort)(C1) Decryption failed

Working ESP8266 log:

(I) (readHanPort) Intermediate segment
(D) (readHanPort) Frame dump (263b):
(D) 68 01 01 68  53 FF 00 01  67 DB 08 53  41 47 59 05 

(D) EA 7A 8E 81  F8 20 00 00  49 2F 87 D0  28 2E 7B E4 

(D) C3 27 CF B6  63 E8 21 6D  A6 05 C1 65  56 8B 6E 5D 

(D) 7A DC 6D 16  4F 12 58 50  04 F2 31 CD  47 3B 2F E3 

(D) 2B 82 CB 43  75 99 6B A4  E3 21 C3 88  8A 65 F1 57 

(D) BD FF F7 AC  1C 91 64 3B  67 E3 D1 B0  6C 6C 31 F9 

(D) 4A 42 8A 1B  A0 8B FB 90  1D 27 86 4A  CD 7F 45 EA 

(D) 58 5C 2D 75  AC CF 07 EE  F3 8C 6A B8  08 98 E1 1E 

(D) 1F 33 33 6E  B2 F7 55 B7  A7 E9 C6 F6  EF 65 4C 64 

(D) D6 B3 D3 B4  EA B8 0E A5  E6 20 C4 FB  C7 1B BC B3 

(D) 9D 3D 93 5F  B2 EB F7 5C  1C 85 E4 E8  73 FC 7E E3 

(D) 30 14 E7 EB  FE E6 A8 91  CC A0 C5 2A  4F 89 23 B7 

(D) CA 02 A9 9A  8F 42 9A 8D  14 65 4B 1F  DD 05 AE 70 

(D) B8 61 74 B5  CA 3F 09 C5  B9 C6 D3 59  93 D5 84 D2 

(D) DB 1D 5A D0  15 2B 33 5A  BB 2F 9B B1  80 E4 1A 9D 

(D) 60 8F 5F 9D  72 22 FA 2D  C0 06 16 FB  93 FA AD B8 

(D) CF 27 DC B0  6E 1D 16 

(I) (readHanPort) Final segment
(D) (readHanPort) Frame dump (19b):
(D) 68 0D 0D 68  53 FF 11 01  67 18 45 BF  6E F7 F4 45 

(D) 5E E3 16 

(D) (readHanPort) Frame dump (271b):
(D) 68 00 00 68  53 FF 10 01  67 DB 08 53  41 47 59 05 

(D) EA 7A 8E 81  F8 20 00 00  49 2F 0F 80  0B F0 17 0C 

(D) 07 E6 03 11  04 12 23 0F  00 FF C4 02  02 23 09 0C 

(D) 07 E6 03 11  04 12 23 0F  00 FF C4 02  09 06 01 00 

(D) 01 08 00 FF  06 00 05 44  6E 02 02 0F  00 16 1E 09 

(D) 06 01 00 02  08 00 FF 06  00 00 2B E7  02 02 0F 00 

(D) 16 1E 09 06  01 00 01 07  00 FF 06 00  00 0B 9B 02 

(D) 02 0F 00 16  1B 09 06 01  00 02 07 00  FF 06 00 00 

(D) 00 00 02 02  0F 00 16 1B  09 06 01 00  20 07 00 FF 

(D) 12 09 1B 02  02 0F FF 16  23 09 06 01  00 34 07 00 

(D) FF 12 09 3A  02 02 0F FF  16 23 09 06  01 00 48 07 

(D) 00 FF 12 09  3A 02 02 0F  FF 16 23 09  06 01 00 1F 

(D) 07 00 FF 12  04 47 02 02  0F FE 16 21  09 06 01 00 

(D) 33 07 00 FF  12 00 39 02  02 0F FE 16  21 09 06 01 

(D) 00 47 07 00  FF 12 00 A4  02 02 0F FE  16 21 09 06 

(D) 01 00 0D 07  00 FF 10 03  D7 02 02 0F  FD 16 FF 09 

(D) 0C 31 37 38  32 31 30 32  35 32 38 37  38 45 16 

(D) (readHanPort) System title:
(D) 53 41 47 59  05 EA 7A 8E  

(D) (readHanPort) Initialization vector:
(D) 53 41 47 59  05 EA 7A 8E  00 00 49 2F  

(D) (readHanPort) Additional authenticated data:
(D) 20 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 

(D) 00 

(D) (readHanPort) Authentication tag:
(D) 00 00 00 00  00 00 00 00  00 00 00 00  

(D) (readHanPort) Valid data, start at byte 44
(V) (AmsDataStorage) Time is: 1647538514

Hardware information:

Relevant firmware information:

Additional context Add any other context about the problem here.

ArnieO commented 2 years ago

Did you try the pre compiled code available here? https://github.com/gskjold/AmsToMqttBridge/releases

tyler123durden commented 2 years ago

Yes, I'm using compiled release version 2.0.11 and also 2.0.5 I think. Then I tried to setup the dev environment but got to strange xtense compile not found error.

tyler123durden commented 2 years ago

I've got a development setup now up an running and as far as I understand mbetls_gcm_auth_decrypt will return an MBEDTLS_ERR_GCM_BAD_INPUT error when no authentication data is provided. Intern in mbedtls_gcm_finish this will trigger:

    if( tag_len > 16 || tag_len < 4 )
        return( MBEDTLS_ERR_GCM_BAD_INPUT );

because tag_len is 0, which is authkeylen from our input.

So we could either ignore authentication related errors or use dedicated decryption calls without authentication stuff. The below version works for me on ESP32

        #elif defined(ESP32)
            uint8_t cipher_text[len - authkeylen - 5];
            memcpy(cipher_text, ptr, len - authkeylen - 5);

            mbedtls_gcm_context m_ctx;
            mbedtls_gcm_init(&m_ctx);
            int success = mbedtls_gcm_setkey(&m_ctx, MBEDTLS_CIPHER_ID_AES, config->encryption_key, 128);
            if (0 != success) {
                return HDLC_ENCRYPTION_KEY_FAILED;
            }
            if (0<authkeylen) {
                success = mbedtls_gcm_auth_decrypt(&m_ctx, sizeof(cipher_text), config->initialization_vector, sizeof(config->initialization_vector),
                    config->additional_authenticated_data, aadlen, config->authentication_tag, authkeylen,
                    cipher_text, (unsigned char*)(ptr));
                if (authkeylen > 0 && success == MBEDTLS_ERR_GCM_AUTH_FAILED) {
                    return HDLC_ENCRYPTION_AUTH_FAILED;
                } else if(success == MBEDTLS_ERR_GCM_BAD_INPUT) {
                    return HDLC_ENCRYPTION_DECRYPT_FAILED;
                }
            }
            else {
                mbedtls_gcm_starts(&m_ctx, MBEDTLS_GCM_DECRYPT, config->initialization_vector, sizeof(config->initialization_vector),NULL, 0);
                if (0 != success) {
                    return HDLC_SOME_ERROR_TBD1;
                }
                success = mbedtls_gcm_update(&m_ctx, sizeof(cipher_text), cipher_text, (unsigned char*)(ptr));
                if (0 != success) {
                    return HDLC_SOME_ERROR_TBD2;
                }
            }
            mbedtls_gcm_free(&m_ctx);
        #endif
ArnieO commented 2 years ago

@gskjold : Help me remember; I had the impression decryption has been verified some time ago on ESP32-based hardware?

gskjold commented 2 years ago

@ArnieO Yes, but only for encryption with both keys.

@tyler123durden Thank you for providing input to a solution, I will try to include this in the upcoming 2.1 release if possible.

tyler123durden commented 2 years ago

great. Also great work and project!

I've seen that I forgot to check error from mbedtls_gcm_starts. Another minor drawback in the above code ist that in error cases mbedtls_gcm_free will not get called, which may lead to a memory leak.