internal static bool verifyChallenger(CosemParameters parameters, CosemConnection connection, byte[] data) { if (data == null || data.Length == 0) { return(false); } try { byte[] calculated = new byte[0]; switch (parameters.authenticationType.innerEnumValue) { case AuthenticationType.InnerEnum.PUBLIC: case AuthenticationType.InnerEnum.LLS: throw new System.InvalidOperationException(); case AuthenticationType.InnerEnum.HLS: calculated = aes128(connection.challengeServerToClient, parameters.llsHlsSecret); break; case AuthenticationType.InnerEnum.HLS_MD5: calculated = md5(connection.challengeClientToServer, parameters.llsHlsSecret); break; case AuthenticationType.InnerEnum.HLS_SHA1: calculated = sha1(connection.challengeClientToServer, parameters.llsHlsSecret); break; case AuthenticationType.InnerEnum.HLS_GMAC: if (data[0] != SC_AUTHENTICATION) { return(false); } System.IO.MemoryStream stream = new System.IO.MemoryStream(); stream.WriteByte(SC_AUTHENTICATION); stream.Write(parameters.ak, 0, parameters.ak.Length); stream.Write(connection.challengeClientToServer, 0, connection.challengeClientToServer.Length); //connection.serverInvocationCounter = BitConverter.ToInt32(helper.extensions.copyOfRange(data, 1, 5), 0); var aux = helper.extensions.copyOfRange(data, 1, 5); connection.serverInvocationCounter = BitConverter.ToInt32(new byte[] { (aux[3]), (aux[2]), (aux[1]), (aux[0]) }, 0); data = helper.extensions.copyOfRange(data, 5, data.Length); CosemParameters cosemParams = new CosemParameters(); cosemParams.setSystemTitle(connection.serverSysTitle); cosemParams.setEk(parameters.ek); calculated = Security.aesGcm(new byte[0], stream.ToArray(), cosemParams, connection.serverInvocationCounter); break; default: throw new System.ArgumentException(); } return(Enumerable.SequenceEqual(data, calculated)); } catch (IOException) { throw new DlmsException(DlmsException.DlmsExceptionReason.INTERNAL_ERROR); } }
internal static byte[] processChallanger(CosemParameters parameters, CosemConnection connection) { try { switch (parameters.authenticationType.innerEnumValue) { case AuthenticationType.InnerEnum.PUBLIC: case AuthenticationType.InnerEnum.LLS: throw new System.InvalidOperationException(); case AuthenticationType.InnerEnum.HLS: return(aes128(connection.challengeServerToClient, parameters.llsHlsSecret)); case AuthenticationType.InnerEnum.HLS_MD5: return(md5(connection.challengeServerToClient, parameters.llsHlsSecret)); case AuthenticationType.InnerEnum.HLS_SHA1: return(sha1(connection.challengeServerToClient, parameters.llsHlsSecret)); case AuthenticationType.InnerEnum.HLS_GMAC: int ivCounter = parameters.getInvocationCounter(); System.IO.MemoryStream data = new System.IO.MemoryStream(); data.WriteByte(SC_AUTHENTICATION); data.Write(parameters.ak, 0, parameters.ak.Length); data.Write(connection.challengeServerToClient, 0, connection.challengeServerToClient.Length); System.IO.MemoryStream stream = new System.IO.MemoryStream(); stream.WriteByte(SC_AUTHENTICATION); stream.WriteByte((byte)(ivCounter >> 24)); stream.WriteByte((byte)(ivCounter >> 16)); stream.WriteByte((byte)(ivCounter >> 8)); stream.WriteByte((byte)(ivCounter)); byte[] aux = Security.aesGcm(new byte[0], data.ToArray(), parameters, ivCounter); stream.Write(aux, 0, aux.Length); return(stream.ToArray()); default: throw new System.ArgumentException(); } } catch (IOException) { throw new DlmsException(DlmsException.DlmsExceptionReason.INTERNAL_ERROR); } }