There is problem with SHA-256 authentication mode in Gurux.DLMS.cpp library. If you see method CGXSecure::Secure input data for hash are incorrectly calculated. IEC 62056-5-3 says that in Pass 3 authentication data should be calculated as follows:
You are calculating hash as follows:
SHA-256 (StoC || HLS Secret)
Very probably also SHA-256 algorithm implemented in CGXDLMSSha256::Encrypt is not correct. I started debug it and see a few weird things. For example if input data are 58 bytes length, method takes first 6 bytes and give them to CGXDLMSSha256::Final method (instead of appending 6 bytes on end). So remaining 58 - 6 = 52 bytes are not taken into account. Also in method CGXDLMSSha256::Update there is dangerous operation on following line:
Implementation of CGXDLMSSha256::Encrypt method is bad. I have replaced it with my own implementation and now I succeed login to meter.
If you want I can send you fixed files. Unfortunately i can upload here only images.
Order of fields is important. The result is different in Pass 3 and Pass 4. You should change order of fields in Pass 4, because the following code in CGXCommunication::InitializeConnection will fail even if response from meter is good.
Implementation of
Implementation of CGXDLMSSha256::Encrypt method is bad. I have replaced it with my own implementation and now I succeed login to meter.
If you want I can send you fixed files. Unfortunately i can upload here only images.
Hi Jan,
Hi Jan,
You are right. I just check SHA-256 from Green Book. We'll fix this.
BR,
Mikko
Don't forget that input data
Don't forget that input data are composed differently in pass 3 and pass 4.
Hi Ján,
Hi Ján,
This is now fixed. Get the latest version. Your name is added to credits.
Thank you for this information.
BR,
Mikko
Thank you. I have reviewed
Thank you. I have reviewed your changes. I dont see differentiation between step3 and step4. Please see GreenBook, chapter 9.2.7.4, Table 42.
Pass 3:
SHA-256(HLS_Secret || SystemTitle-C || SystemTitle-S || StoC || CtoS)
Pass 4:
SHA-256(HLS_Secret || SystemTitle-S || SystemTitle-C || CtoS || StoC)
Order of fields is important. The result is different in Pass 3 and Pass 4. You should change order of fields in Pass 4, because the following code in CGXCommunication::InitializeConnection will fail even if response from meter is good.
if (m_Parser->IsAuthenticationRequired())
{
if ((ret = m_Parser->GetApplicationAssociationRequest(data)) != 0 ||
(ret = ReadDataBlock(data, reply)) != 0 ||
(ret = m_Parser->ParseApplicationAssociationResponse(reply.GetData())) != 0)
{
return ret;
}
}
Hi Jan,
Hi Jan,
This is now fixed. Get the latest version.
BR,
Mikko