include "msgdigest.s7i";
include "bin32.s7i";
const func string: (in string: stri1) >< (in string: stri2) is func
result
var string: xorResult is "";
local
var integer: index is 0;
begin
if length(stri1) <> length(stri2) then
raise RANGE_ERROR;
else
xorResult := "\0;" mult length(stri1);
for index range 1 to length(stri1) do
xorResult @:= [index] chr(ord(bin32(stri1[index]) >< bin32(stri2[index])));
end for;
end if;
end func;
const func string: hmac (in digestAlgorithm: digestAlg, in var string: cryptoKey,
in string: message) is func
result
var string: authenticationCode is "";
local
var integer: blockSize is 0;
var string: o_key_pad is "";
var string: i_key_pad is "";
begin
blockSize := blockSize(digestAlg);
if length(cryptoKey) > blockSize then
cryptoKey := msgDigest(digestAlg, cryptoKey);
end if;
cryptoKey &:= "\0;" mult (blockSize - length(cryptoKey));
o_key_pad := ("\16#5c;" mult blockSize) >< cryptoKey;
i_key_pad := ("\16#36;" mult blockSize) >< cryptoKey;
authenticationCode := msgDigest(digestAlg, o_key_pad &
msgDigest(digestAlg, i_key_pad & message));
end func;
const func string: p_hash (in digestAlgorithm: digestAlg, in string: secret, in string: seed,
in integer: length) is func
result
var string: digest is "";
local
var string: a is "";
begin
a := hmac(digestAlg, secret, seed);
digest := hmac(digestAlg, secret, a & seed);
while length(digest) < length do
a := hmac(digestAlg, secret, a);
digest &:= hmac(digestAlg, secret, a & seed);
end while;
digest := digest[.. length];
end func;
const func string: pseudoRandomFunction (in string: secret, in string: label,
in string: seed, in integer: length) is func
result
var string: digest is "";
local
var integer: halveLength is 0;
begin
halveLength := succ(length(secret)) div 2;
digest := p_hash(MD5, secret[.. halveLength], label & seed, length) ><
p_hash(SHA1, secret[length(secret) - halveLength + 1 ..], label & seed, length);
end func;
const func string: keyBlockFunction (in string: secret, in string: random,
in integer: length) is func
result
var string: keyBlock is "";
local
var integer: count is 1;
begin
while length(keyBlock) < length do
keyBlock &:= md5(secret &
sha1(str(chr(ord('A') + count - 1)) mult count &
secret & random));
incr(count);
end while;
keyBlock := keyBlock[.. length];
end func;
const func string: mgf1Sha1 (in string: mgfSeed, in integer: maskLen) is func
result
var string: mask is "";
local
const integer: hLen is 20;
var integer: counter is 0;
begin
for counter range 0 to pred(maskLen) mdiv hLen do
mask &:= sha1(mgfSeed & bytes(counter, UNSIGNED, BE, 4));
end for;
mask := mask[.. maskLen];
end func;