Ciphered context and GMAC

In order to exchange information, a client and a server shall enter in a logical connection called an application association (AA) to be mutually aware of the set of rules that govern the exchanges. This set of rules is called the application context of the AA. The application context determines: (1) the referencing style of COSEM attributes and methods, short name (SN) or logical name (LN) ; and (2) whether ciphering is used or not. There are therefore 4 application contexts available: LN, SN, LN_WITH_CIPHERING and SN_WITH_CIPHERING.

When establishing an AA, an authentication mechanism can be used to identify the client alone or both the client and the server. There are two kinds of mechanism names available: LOW_SECURITY that identifies the client alone and several variants of HIGH_SECURITY that identify both the client and the server.

We show here the establishment of an LN_WITH_CIPHERING application association using the HIGH_SECURITY_GMAC authentication mechanism.

It is a 4 passes procedure:

Pass 1: the client sends an AssociationRequest (AARQ)

The AssociationRequest looks like:

<AssociationRequest>
  <ApplicationContextName Value="LN_WITH_CIPHERING" >
  <CallingAPTitle Value="\CTT00000" >
  <SenderACSERequirements Value="1" >
  <MechanismName Value="HIGH_SECURITY_GMAC" >
  <CallingAuthenticationValue Value="44113E06C4202C30022F7F03BA" >
  <GeneralGloCiphering>
    <SystemTitle Value="\CTT00000" >
    <CipheredService Value="303A8B88AC4813BE2F92968FEB639438E2194FC122AF44FC41B85DB4E3ECFD" >
  <GeneralGloCiphering>
<AssociationRequest>

  • ApplicationContextName indicates a ciphered context:  LN_WITH_CIPHERING.
  • CallingAPTitle is the system title of the caller (the client). It is a 8 octets value, with the 3 leading octets being the "FLAGId".
  • SenderACSERequirement is  "1" when a mechanism name is specified.
  • MechanismName is HIGH_SECURITY_GMAC, therefore passes 3 and 4 will be needed (see below).
  • CallingAuthenticationValue is an arbitrary octet-string of 8 to 64 octets. It is a challenge of the client to the server (CtoS), it is needed in pass 4.
  • The last member is a GeneralGloCiphering, which is ''carried'' by the AssociationRequest. How do we build it?

Let us first look to an AARQ with a non ciphered context, and using the LOW_SECURITY mechanism:

<AssociationRequest>
  <ApplicationContextName Value="LN" >
  <SenderACSERequirements Value="1" >
  <MechanismName Value="LOW_SECURITY" >
  <CallingAuthenticationValue Value="\12345678" >
  <InitiateRequest>
    <ProposedDlmsVersionNumber Value="06" >
    <ProposedConformance>
      <ConformanceBit Name="Action" >
      <ConformanceBit Name="EventNotification" >
      <ConformanceBit Name="SelectiveAccess" >
      <ConformanceBit Name="Set" >
      <ConformanceBit Name="Get" >
      <ConformanceBit Name="Access" >
      <ConformanceBit Name="DataNotification" >
      <ConformanceBit Name="MultipleReferences" >
      <ConformanceBit Name="BlockTransferWithAction" >
      <ConformanceBit Name="BlockTransferWithSetOrWrite" >
      <ConformanceBit Name="BlockTransferWithGetOrRead" >
      <ConformanceBit Name="Attribute0SupportedWithGet" >
      <ConformanceBit Name="PriorityMgmtSupported" >
      <ConformanceBit Name="Attribute0SupportedWithSet" >
      <ConformanceBit Name="GeneralBlockTransfer" >
      <ConformanceBit Name="GeneralProtection" >
    <ProposedConformance>
    <ProposedMaxPduSize Value="FFFF" >
  <InitiateRequest>
<AssociationRequest>

The members ApplicationContextName, SenderACSERequirement, MechanismName are equivalent to the ones listed above. CallingAuthenticationValue is a password. The last member is a plain InitiateRequest service ''carried'' by the AssociationRequest.

However, in an AARQ for a ciphered-context, the ''carried'' service must be a ciphered InitiateRequest, that we have to embed into a GeneralGloCiphering service, like in the following:

1 - We start with a plain InitiateRequest

<InitiateRequest>
  <ProposedDlmsVersionNumber Value="06" >
  <ProposedConformance>
    <ConformanceBit Name="Action" >
    <ConformanceBit Name="EventNotification" >
    <ConformanceBit Name="SelectiveAccess" >
    <ConformanceBit Name="Set" >
    <ConformanceBit Name="Get" >
    <ConformanceBit Name="Access" >
    <ConformanceBit Name="DataNotification" >
    <ConformanceBit Name="MultipleReferences" >
    <ConformanceBit Name="BlockTransferWithAction" >
    <ConformanceBit Name="BlockTransferWithSetOrWrite" >
    <ConformanceBit Name="BlockTransferWithGetOrRead" >
    <ConformanceBit Name="Attribute0SupportedWithGet" >
    <ConformanceBit Name="PriorityMgmtSupported" >
    <ConformanceBit Name="Attribute0SupportedWithSet" >
    <ConformanceBit Name="GeneralBlockTransfer" >
    <ConformanceBit Name="GeneralProtection" >
  <ProposedConformance>
  <ProposedMaxPduSize Value="FFFF" >
<InitiateRequest>

2 - We convert it to a plain PDU using the xmlpdu library

01000000065F1F040060FEDFFFFF

3 - We cipher the plain PDU using the GCMdll library

(The API (chm file) of the GCMDll is here, if it is blocked, then click-right on the file-name, select properties and click Unblock as explained here).

The Cipher routine takes several parameters. SecurityControl is set to AUTHENTICATION_AND_ENCRYPTION and SystemTitle is our (client) system title (CTT00000). The returned ciphered content is:

30 3A8B88AC 4813BE2F92968FEB639438E2194F C122AF44FC41B85DB4E3ECFD

The first octet (30) indicates AUTHENTICATION_AND_ENCRYPTION, the 4 next octets store a frame-counter value (that is automatically generated by GCMDll) the next 14 octets are the encryption of the 14 octets plain PDU and finally, the last 12 octets are the authentication tag or Galois message authentication code (GMAC).

4 - We create a GeneralGloCiphering or a glo_InitiateRequest using the ciphered content.

Here is the GeneralGloCiphering:

<GeneralGloCiphering>
  <SystemTitle Value="\CTT00000" >
  <CipheredService Value="303A8B88AC4813BE2F92968FEB639438E2194FC122AF44FC41B85DB4E3ECFD" >
<GeneralGloCiphering>

The first member is the client system-title, the second member is the ciphered content as created above.

Some meters do not support the ''general'' services. In such cases, we generate a glo_InitiateRequest:

<glo_InitiateRequest Value="303A8B88AC4813BE2F92968FEB639438E2194FC122AF44FC41B85DB4E3ECFD" >

5 - We embed the GeneralGloCipering or the glo_InitiateRequest service in the AssociationRequest

The result is the same AssociationRequest as above that we translate into a PDU (using xmlpdu) that we send to the server over the supporting transport layer (WRAPPER or HDLC).

Pass 2: the client receives an AssociationResponse (AARE)

The server replies with a PDU what we decode as an AssociationResponse:

<AssociationResponse>
  <ApplicationContextName Value="LN_WITH_CIPHERING" >
  <AssociationResult Value="00" >
  <ResultSourceDiagnostic>
    <ACSEServiceUser Value="0E" >
  <ResultSourceDiagnostic>
  <RespondingAPTitle Value="\ICU00000" >
  <ResponderACSERequirement Value="1" >
  <MechanismName Value="HIGH_SECURITY_GMAC" >
  <RespondingAuthenticationValue Value="D28566B5F16E0B49080785B7550161" >
  <GeneralGloCiphering>
    <SystemTitle Value="\ICU00000" >
    <CipheredService Value="303A8B88B10BBA17AA4D7D9742685C3759F4525CB21CD400CCBE001317B926" >
  <GeneralGloCiphering>
<AssociationResponse>

  • ApplicationContextName indicates a ciphered context:  LN_WITH_CIPHERING.
  • AssociationResult is 0x00 which means accepted. However, the association is not yet fully established because the passes 3 and 4 are still missing. This is indicated by the value 0x0E (authentication-required) of ACSEServiceUser.
  • RespondingAPTitle is the system title of the the server.
  • ResponderACSERequirement is always "1" when a mechanism name is specified.
  • MechanismName is HIGH_SECURITY_GMAC.
  • RespondingAuthenticationValue is an arbitrary octet-string of 8 to 64 octets, it is a challenge of the server to the client  (StoC), it is needed in pass 3.
  • The last member is a GeneralGloCiphering that should carry the ciphered content of an InitiateResponse. To check that it is indeed the case, we pass the  CipheredService ''Value'' (converted from hex to binary) as well as the SystemTitle, to the Decipher function of the GCMDll library. If the function returns FAILED, then we cannot decode the GeneralGloCiphering and we abort the association establishment process. Otherwise, the function returns the plain PDU of the of ciphered content:

0800065F1F0400601ADD01000007

..which we convert to xml using the xmlpdu library:

<InitiateResponse>
  <NegotiatedDlmsVersionNumber Value="06" >
  <NegotiatedConformance>
    <ConformanceBit Name="Action" >
    <ConformanceBit Name="SelectiveAccess" >
    <ConformanceBit Name="Set" >
    <ConformanceBit Name="Get" >
    <ConformanceBit Name="Access" >
    <ConformanceBit Name="DataNotification" >
    <ConformanceBit Name="MultipleReferences" >
    <ConformanceBit Name="BlockTransferWithSetOrWrite" >
    <ConformanceBit Name="BlockTransferWithGetOrRead" >
    <ConformanceBit Name="GeneralBlockTransfer" >
    <ConformanceBit Name="GeneralProtection" >
  <NegotiatedConformance>
  <NegotiatedMaxPduSize Value="0100" >
  <VaaName Value="0007" >
<InitiateResponse>

We check the negotiated values and if there are acceptable we continue with pass 3.

Pass 3: the client replies to the server challenge

During pass 2 (see above) , the server sent a ''server to client'' challenge (StoC) in the RespondingAuthenticationValue member or its AARE. We have to compute the response to this challenge - F(StoC) :

We start from StoC:

D28566B5F16E0B49080785B7550161

We pass this (plain) octet string to the Cipher routine of GCMDll, with SecurityControl set to AUTHENTICATION, and the (client)  SystemTitle . The routine returns:

10 3A8B88B1 D28566B5F16E0B49080785B7550161 1592204757D4B6F91FE09C60

The first octet (10) indicates AUTHENTICATION, the 4 next octets are a frame-counter value (automatically generated), the next 15 octets are exactly the plain octet-string (because we didn't request ENCRYPTION) and the 12 last octets are the authentication tag. We concatenate the elements in bold to yield the following octet-string:

103A8B88B11592204757D4B6F91FE09C60

This is F(StoC), i.e. the response to the server challenge. We now invoke the reply_to_HLS_authentication method of the ''current association object'', passing the response to the server challenge (invoking a method requires an Action or an Access service):

<ActionRequest>
  <ActionRequestNormal>
    <InvokeIdAndPriority Value="C1" >
    <MethodDescriptor>
      <ClassId Value="000F" >
      <InstanceId Value="0000280000FF" >
      <MethodId Value="01" >
    <MethodDescriptor>
    <MethodInvocationParameters>
      <OctetString Value="103A8B88B11592204757D4B6F91FE09C60" >
    <MethodInvocationParameters>
  <ActionRequestNormal>
<ActionRequest>

  • We use an ActionRequest of variant ActionRequestNormal
  • The members of the MethodDescriptor are: 0x0F is the class-id of a LNAssociation object (by definition); 0x0000280000FF is the logical-name of the current association (by definition) and 0x01 is the method-id of the reply_to_HLS_authentication method (by definition).
  • The MethodInvocationParameters is an OctetString carrying F(StoC).

Pass 4: the server replies to the client challenge

The server sends an ActionResponse:

<ActionResponse>
  <ActionResponseNormal>
    <InvokeIdAndPriority Value="C1" >
    <Result Value="Success" >
    <ReturnParameters>
      <Data>
        <OctetString Value="103A8B88B27608AFE96F688823D8F127C2" >
      <Data>
    <ReturnParameters>
  <ActionResponseNormal>
<ActionResponse>

The "Success" Result indicates that the server could verify the F(StoC) passed before. The server accepts the authenticated of the client.

The  ReturnParameters is F(CtoS), the server response to the client challenge passed in the CallingAuthenticationValue member of pass 1. We check this value as follows:

We call Cipher passing CtoS (44113E06C4202C30022F7F03BA), the server SystemTitle (ICU00000) and the frame counter (3A8B88B2). The routine returns the  the following result:

10 3A8B88B2 44113E06C4202C30022F7F03BA 7608AFE96F688823D8F127C2

We verify that the concatenation of the tree bold elements is the OctetString value returned by the ActionResponse. If yes, then the client accepts the quthentication of the server and the association is established.