using Unity.Collections; namespace Unity.Networking.Transport { public static class HMACSHA256 { /// /// Writes 32 bytes to result using key and message /// /// Key data /// Length of the key data /// Message to hash /// Length of the message /// Where to write resulting 32 bytes hash public static unsafe void ComputeHash(byte* keyValue, int keyArrayLength, byte* messageBytes, int messageLength, byte* result) { const int B = 64; const int sha256SizeBytes = 32; const byte ipad = 0x36; const byte opad = 0x5C; var shorterKey = stackalloc byte[sha256SizeBytes]; var sha256State = SHA256.SHA256State.Create(); if (keyArrayLength > B) { sha256State.Update(keyValue, keyArrayLength); sha256State.Final(shorterKey); keyValue = shorterKey; keyArrayLength = sha256SizeBytes; } var kx = stackalloc byte[B]; for (var i = 0; i < keyArrayLength; i++) kx[i] = (byte) (ipad ^ keyValue[i]); for (var i = keyArrayLength; i < B; i++) kx[i] = ipad; sha256State = SHA256.SHA256State.Create(); sha256State.Update(kx, B); sha256State.Update(messageBytes, messageLength); sha256State.Final(result); for (var i = 0; i < keyArrayLength; i++) kx[i] = (byte) (opad ^ keyValue[i]); for (var i = keyArrayLength; i < B; i++) kx[i] = opad; sha256State = SHA256.SHA256State.Create(); sha256State.Update(kx, B); sha256State.Update(result, sha256SizeBytes); sha256State.Final(result); } } }