include "bin32.s7i";
include "cipher.s7i";
include "des.s7i";
const type: tdesState is sub noCipherState struct
var desSubKeyType: encryptionSubKey1 is desSubKeyType.value;
var desSubKeyType: encryptionSubKey2 is desSubKeyType.value;
var desSubKeyType: encryptionSubKey3 is desSubKeyType.value;
var desSubKeyType: decryptionSubKey1 is desSubKeyType.value;
var desSubKeyType: decryptionSubKey2 is desSubKeyType.value;
var desSubKeyType: decryptionSubKey3 is desSubKeyType.value;
var string: cipherBlock is "";
end struct;
type_implements_interface(tdesState, cipherState);
const func integer: blockSize (TDES) is 8;
const func tdesState: setTdesKey (in string: desKey, in string: initializationVector) is func
result
var tdesState: state is tdesState.value;
begin
state.encryptionSubKey1 := setDesKey(desKey[1 fixLen 8]);
state.decryptionSubKey1 := reverseKeyScheduleOrder(state.encryptionSubKey1);
state.encryptionSubKey2 := setDesKey(desKey[9 fixLen 8]);
state.decryptionSubKey2 := reverseKeyScheduleOrder(state.encryptionSubKey2);
state.encryptionSubKey3 := setDesKey(desKey[17 fixLen 8]);
state.decryptionSubKey3 := reverseKeyScheduleOrder(state.encryptionSubKey3);
state.cipherBlock := initializationVector;
end func;
const func cipherState: setCipherKey (TDES, in string: cipherKey,
in string: initializationVector) is
return toInterface(setTdesKey(cipherKey, initializationVector));
const func string: encode (inout tdesState: state, in string: plaintext) is func
result
var string: encoded is "";
local
var integer: index is 0;
var integer: subIndex is 0;
var string: dataBlock is "";
var string: cipherBlock is "";
begin
for index range 1 to length(plaintext) step blockSize(TDES) do
dataBlock := "";
for subIndex range 1 to blockSize(TDES) do
dataBlock &:= chr(ord(bin32(plaintext[pred(index + subIndex)]) ><
bin32(state.cipherBlock[subIndex])));
end for;
cipherBlock := processDesBlock(state.encryptionSubKey3,
processDesBlock(state.decryptionSubKey2,
processDesBlock(state.encryptionSubKey1, dataBlock)));
state.cipherBlock := cipherBlock;
encoded &:= cipherBlock;
end for;
end func;
const func string: decode (inout tdesState: state, in string: encoded) is func
result
var string: plaintext is "";
local
var integer: index is 0;
var integer: subIndex is 0;
var string: cipherBlock is "";
var string: dataBlock is "";
var string: plainBlock is "";
begin
for index range 1 to length(encoded) step blockSize(TDES) do
cipherBlock := encoded[index fixLen blockSize(TDES)];
dataBlock := processDesBlock(state.decryptionSubKey1,
processDesBlock(state.encryptionSubKey2,
processDesBlock(state.decryptionSubKey3, cipherBlock)));
for subIndex range 1 to blockSize(TDES) do
plaintext &:= chr(ord(bin32(dataBlock[subIndex]) ><
bin32(state.cipherBlock[subIndex])));
end for;
state.cipherBlock := cipherBlock;
end for;
end func;