Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Dark

Collapse
SHARUR
Community Wiki DLMS/COSEM Tools
Search Sign in

Why does HLS 5 (GMAC) mutual authentication fail on Server Proof verification during StoC/CtoS challenge exchange?

Scheduled Pinned Locked Moved General Discussion
dlmscosemhls-5gmacsecurity-suite
10 Posts 5 Posters 46 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
  • A Offline
    A Offline
    alex_turner
    wrote on last edited by
    #1

    [!WARNING]
    Technical Redaction & Safe Harbor Notice:
    All communication captures, system titles, and cryptographic parameters in this thread have been sanitized and neutralized. Real utility meter identifiers, production encryption keys (GUEK/GAK/MK), SIM IMSIs, and proprietary network envelopes have been substituted with standard IEC 62056 synthetic test vectors. Do not post unredacted production captures or live cryptographic keys.

    We are implementing High Level Security 5 (HLS 5 GMAC) mutual authentication over IEC 62056-47 TCP Wrapper for Security Suite 1 (Association LN OBIS 0.0.40.0.0.255, Management Client 0x0001).

    The initial AARQ (0x60) and AARE (0x61) handshake succeeds, and the meter returns a 16-byte Server-to-Client challenge (StoC = 50 36 77 52 4A 32 31 46 11 22 33 44 55 66 77 88).
    Next, our client generates the Client-to-Server challenge response (CtoS), encapsulates it inside Action-Request-Normal (Class 15 Method 1 reply_to_HLS_authentication), and transmits it to the meter. The meter accepts the CtoS response and replies with Action-Response-Normal containing the Server Proof (StoC authentication tag).

    However, when our HES client verifies the received Server Proof, the locally computed GMAC authentication tag fails to match the meter's returned tag, causing our HES to abort the association with an invalid-password / challenge-mismatch exception!

    Here is our client Action-Request (CtoS challenge):

    00 01 00 01 00 01 00 28 C3 01 C1 00 0F 00 00 28 00 00 FF 01 01 09 11 10 00 00 00 01 1A 52 FE 7D D3 E7 27 48 97 3C 1E 28
    

    And here is the meter's Action-Response containing the Server Proof:

    00 01 00 01 00 01 00 1E C7 01 C1 00 01 09 11 10 00 00 00 01 88 F0 1A 2B 3C 4D 99 11 22 33 44 55 66
    

    Why is our client failing to verify the meter's Server Proof?

    1 Reply Last reply
    0
    • D Offline
      D Offline
      david_miller
      wrote on last edited by
      #2

      Alex, this is one of the most classic identity traps in DLMS Security Suite 1 implementation.

      Per DLMS Green Book 10th Ed Section 9.2.5.3 (High Level Security Mechanism 5) and Table 43 (HLS 5 Standard Test Vectors), HLS 5 uses AES-GCM-128 authentication in two asymmetric directions:

      1. Client to Server Proof (CtoS):
        • Input challenge: StoC (generated by meter)
        • IV Construction: $\text{IV}_{\text{CtoS}} = \text{Client System Title (8B)} \parallel \text{Client Invocation Counter (4B)}$
        • AAD: $\text{Security Control (0x10)} \parallel \text{Authentication Key (GAK)}$
      2. Server to Client Proof (StoC):
        • Input challenge: CtoS (generated by client in AARQ)
        • IV Construction: $\text{IV}_{\text{StoC}} = \text{Server System Title (8B)} \parallel \text{Server Invocation Counter (4B)}$

      Look closely at how your HES client verifies the meter's response:
      If your client code re-used the Client System Title (or client IV) instead of extracting the Server System Title from the AARE response (0x61), the AES-GCM GHASH polynomial state will calculate a completely different tag!

      1 Reply Last reply
      0
      • E Offline
        E Offline
        elena_rostova
        wrote on last edited by
        #3

        David's point regarding System Title directionality is 100% correct. Furthermore, check the Authentication Key (GAK) and Block Cipher Key (GUEK) separation:

        In DLMS Green Book Section 9.2.5.3, HLS 5 authentication strictly uses the Authentication Key (GAK) (e.g. D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF), NOT the Global Unicast Encryption Key (GUEK: 000102030405060708090A0B0C0D0E0F).

        In your Action-Request hex:
        10 00 00 00 01 1A 52 FE 7D D3 E7 27 48 97 3C 1E 28

        • 10: Security Control (0x10 = Global Key, Authenticated Only, Security Suite 1)
        • 00 00 00 01: Client Invocation Counter 1
        • 1A 52 FE ...: 12-byte GMAC tag.

        Notice that 1A 52 FE 7D D3 E7 27 48 97 3C 1E 28 exactly matches the official Green Book Table 43 test vector when StoC is 503677524A323146 and Client System Title is 4D4D4D0000000001! This proves your client computed CtoS correctly, meaning the meter accepted it and incremented its own Invocation Counter to 1 for the Server Proof.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          marcus_vance
          wrote on last edited by
          #4

          Let's look at the meter's returned Server Proof:
          10 00 00 00 01 88 F0 1A 2B 3C 4D 99 11 22 33 44 55 66

          Dissecting the meter's proof:

          • 10: Server Security Control byte
          • 00 00 00 01: Server Invocation Counter (0x00000001)
          • 88 F0 1A 2B 3C 4D 99 11 22 33 44 55: 12-byte Server GMAC Tag

          Per IEC 62056-53 Section 8.4.2 and DLMS Green Book Section 9.2.5.3.2, to verify this Server Proof, your client must execute:
          $$\text{IV} = \text{ServerSystemTitle} (8\text{B}) \parallel \text{ServerIC} (0x00000001)$$
          $$\text{AAD} = \text{0x10} \parallel \text{GAK}$$
          $$\text{Data} = \text{Client Challenge (CtoS extracted from AARQ)}$$

          If your client passed StoC instead of CtoS as the data payload during Server Proof verification, it fails immediately!

          1 Reply Last reply
          0
          • S Offline
            S Offline
            sarah_jenkins
            wrote on last edited by
            #5

            There is also the ACSE Service User Calling Authentication wrapper to verify.

            Per DLMS Green Book 10th Ed Section 9.3.4 (Association LN Class 15), when HLS 5 is used, the calling-authentication-value in AARQ must use the charstring or bitstring choice with tag [0] (ACSE User Information = 14).

            If the HES transmits the initial CtoS challenge in AARQ with an incorrect length (e.g. 8 bytes vs 16 bytes), the meter's internal RNG pads the challenge with zeros, causing the Server Proof calculation to diverge from the client's expectation.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              alex_turner
              wrote on last edited by
              #6

              David and Marcus, you hit the bullseye! I inspected our HES verification method, and we had two distinct bugs:

              1. System Title Inversion: Our code was using client.ciphering.systemTitle to build the IV for both CtoS AND StoC verification, instead of using server.systemTitle (4752580000000001 / GRX00000001) for the Server Proof!
              2. Challenge Inversion: We were hashing StoC against the server response, rather than our original CtoS challenge string.

              Once we passed serverSystemTitle and clientChallenge into the AES-GCM GMAC validator, the computed tag matched 88 F0 1A 2B 3C 4D 99 11 22 33 44 55 with 0 bit errors!

              1 Reply Last reply
              0
              • D Offline
                D Offline
                david_miller
                wrote on last edited by
                #7

                Excellent! Here is the formal mathematical rule for HLS 5 verification symmetry:

                $$\text{CtoS Tag} = \text{GMAC}{\text{GAK}}(\text{SystemTitle}{\text{Client}} \parallel IC_{\text{Client}}, \text{AAD}{\text{0x10}}, \text{StoC})$$
                $$\text{StoC Tag (Server Proof)} = \text{GMAC}
                {\text{GAK}}(\text{SystemTitle}{\text{Server}} \parallel IC{\text{Server}}, \text{AAD}_{\text{0x10}}, \text{CtoS})$$

                Notice the perfect criss-cross symmetry between Challenge Originator and System Title Holder per DLMS Green Book Section 9.2.5.3.

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  elena_rostova
                  wrote on last edited by
                  #8

                  From the meter firmware side, there is one more vital rule: Invocation Counter Anti-Replay on HLS.

                  When the meter receives Action-Request Method 1, it checks:
                  $$IC_{\text{CtoS}} > IC_{\text{last_stored}}$$
                  If the client retransmits CtoS with an old or duplicate $IC$, the meter returns Action-Response-With-Service-Error: hardware-fault (0xC7 0x01 C1 01). Always ensure the client increments its $IC$ before building CtoS!

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    alex_turner
                    wrote on last edited by
                    #9

                    Here is the verified working trace of the complete HLS 5 handshake exchange:

                    1. AARQ with Client Challenge (CtoS😞
                    00 01 00 01 00 01 00 3C 60 3A A1 09 06 07 60 85 74 05 08 01 03 A6 0A 04 08 4D 4D 4D 00 00 00 00 01 8A 02 07 80 8B 07 60 85 74 05 08 02 05 AC 0A 80 08 43 74 6F 53 31 32 33 34 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 7E 1F 04 00
                    
                    1. AARE with Server Challenge (StoC😞
                    00 01 00 01 00 01 00 3C 61 3A A1 09 06 07 60 85 74 05 08 01 03 A2 03 02 01 00 A3 05 A1 03 02 01 00 A6 0A 04 08 47 52 58 00 00 00 00 01 88 02 07 80 89 07 60 85 74 05 08 02 05 AA 0A 80 08 50 36 77 52 4A 32 31 46 BE 10 04 0E
                    
                    1. CtoS Action Request (Method 1) & StoC Server Proof Action Response succeed cleanly.
                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      david_miller
                      wrote on last edited by
                      #10

                      To synthesize this for all DLMS protocol engineers, here is the complete Python Gurux snippet demonstrating bidirectional HLS 5 verification:

                      from gurux_dlms.secure import GXSecure
                      from gurux_dlms.enums import Security, Authentication
                      from gurux_dlms.objects import GXDLMSAssociationLN
                      
                      def verify_hls5_mutual_authentication(client, server_system_title, server_proof_bytes, ctos_challenge):
                          # 1. Extract Server SC, Server IC, and Server GMAC Tag
                          server_sc = server_proof_bytes[0]
                          server_ic = int.from_bytes(server_proof_bytes[1:5], 'big')
                          server_gmac_tag = server_proof_bytes[5:17] # 12 bytes
                          
                          # 2. Build Server IV: Server System Title (8B) || Server IC (4B)
                          iv = server_system_title + server_proof_bytes[1:5]
                          aad = bytes([server_sc])
                          
                          # 3. Calculate Expected Server Proof over original CtoS challenge using GAK
                          expected_proof = GXSecure.secure(
                              client.settings, client.ciphering, server_ic, ctos_challenge, server_system_title
                          )
                          
                          assert server_proof_bytes == expected_proof, "Server Proof Mismatch! Mutual auth failed."
                          print("[+] HLS 5 Mutual Authentication & Server Proof verified successfully!")
                      

                      Summary Checklist for HLS 5 GMAC:

                      1. IV System Title Assignment: CtoS uses Client System Title; Server Proof verification uses Server System Title (Green Book Table 43).
                      2. Key Separation: Use Authentication Key (GAK), not Encryption Key (GUEK).
                      3. Data Payload: CtoS hashes StoC; Server Proof hashes CtoS.
                      4. Anti-Replay: Guarantee monotonic $IC$ incrementation before challenge generation.
                      1 Reply Last reply
                      0

                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                      With your input, this post could be even better 💗

                      Register Login
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      Powered by NodeBB Contributors
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups