create function dbo.Hmac (
@key varbinary(8000)
, @message varbinary(80007936)
)
returns table
with schemabinding as
return (
select HashBytes('SHA2_256', Pads.o + HashBytes('SHA2_256', Pads.i + @message)) as [Hash]
from (values(
Cast( -- keys longer than blocksize are shortened and keys shorter than blocksize are zero-padded
case
when DataLength(@key) > 64 then HashBytes('SHA2_256', @key)
else @key
end as binary(64)) -- keys longer than blocksize are shortened and keysend
shorter than blocksize are zero-padded as binary(64))
, Cast(0x3636363636363636 as bigint) -- Rfc2104 inner padding constant
, Cast(0x5C5C5C5C5C5C5C5C as bigint) -- Rfc2104 outer padding constant
)) as Vars ([key], innerPadding, outerPadding)
cross apply (values(
-- unrolled loop to XOR key and iPad
Cast((Substring(Vars.[key], 1, 8) ^ Vars.innerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 9, 8) ^ Vars.innerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 17, 8) ^ Vars.innerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 25, 8) ^ Vars.innerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 33, 8) ^ Vars.innerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 41, 8) ^ Vars.innerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 49, 8) ^ Vars.innerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 57, 8) ^ Vars.innerPadding) as binary(8))
-- unrolled loop to XOR key and oPad
, Cast((Substring(Vars.[key], 1, 8) ^ Vars.outerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 9, 8) ^ Vars.outerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 17, 8) ^ Vars.outerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 25, 8) ^ Vars.outerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 33, 8) ^ Vars.outerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 41, 8) ^ Vars.outerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 49, 8) ^ Vars.outerPadding) as binary(8))
+ Cast((Substring(Vars.[key], 57, 8) ^ Vars.outerPadding) as binary(8))
)) as Pads (i, o)
);