📄 rijndael_api_ref.pas
字号:
{* rijndael-api-ref.c v2.0 August '99 *}
(* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* --------------------------------- *
* DELPHI *
* Rijndael API *
* --------------------------------- *
* December 2000 *
* *
* Authors: Paulo Barreto *
* Vincent Rijmen *
* *
* Delphi translation by Sergey Kirichenko (ksv@cheerful.com) *
* Home Page: http://rcolonel.tripod.com *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)
unit rijndael_api_ref;
interface
uses rijndael_alg_ref;
const
MAXBC = (256 div 32);
MAXKC = (256 div 32);
MAXROUNDS = 14;
DIR_ENCRYPT = 0; { Are we encrpyting? }
DIR_DECRYPT = 1; { Are we decrpyting? }
MODE_ECB = 1; { Are we ciphering in ECB mode? }
MODE_CBC = 2; { Are we ciphering in CBC mode? }
MODE_CFB1 = 3; { Are we ciphering in 1-bit CFB mode? }
rTRUE = 1; { integer(true) }
rFALSE = 0; { integer(false) }
BITSPERBLOCK = 128; { Default number of bits in a cipher block }
{ Error Codes - CHANGE POSSIBLE: inclusion of additional error codes }
BAD_KEY_DIR = -1; { Key direction is invalid, e.g., unknown value }
BAD_KEY_MAT = -2; { Key material not of correct length }
BAD_KEY_INSTANCE = -3; { Key passed is not valid }
BAD_CIPHER_MODE = -4; { Params struct passed to cipherInit invalid }
BAD_CIPHER_STATE = -5; { Cipher in wrong state (e.g., not initialized) }
BAD_CIPHER_INSTANCE = -7;
{ CHANGE POSSIBLE: inclusion of algorithm specific defines }
MAX_KEY_SIZE = 64; { # of ASCII char's needed to represent a key }
MAX_IV_SIZE = (BITSPERBLOCK div 8); { # bytes needed to represent an IV }
type
{ Typedef'ed data storage elements. Add any algorithm specific
parameters at the bottom of the structs as appropriate. }
word8 = byte; // unsigned 8-bit
word16 = word; // unsigned 16-bit
word32 = longword; // unsigned 32-bit
TByteArray = array [0..MaxInt div sizeof(Byte)-1] of Byte;
PByte = ^TByteArray;
{ The structure for key information }
PkeyInstance = ^keyInstance;
keyInstance = packed record
direction: Byte; { Key used for encrypting or decrypting? }
keyLen: integer; { Length of the key }
keyMaterial: array [0..MAX_KEY_SIZE+1-1] of char; { Raw key data in ASCII, e.g., user input or KAT values }
{ The following parameters are algorithm dependent, replace or add as necessary }
blockLen: integer; { block length }
keySched: TArrayRK; { key schedule }
end; {* keyInstance *}
TkeyInstance = keyInstance;
{ The structure for cipher information }
PcipherInstance = ^cipherInstance;
cipherInstance = packed record
mode: Byte; // MODE_ECB, MODE_CBC, or MODE_CFB1
IV: array [0..MAX_IV_SIZE-1] of Byte; // A possible Initialization Vector for ciphering
{ Add any algorithm specific parameters needed here }
blockLen: integer; // Sample: Handles non-128 bit block sizes (if available)
end; {* cipherInstance *}
TcipherInstance = cipherInstance;
{ Function prototypes }
function makeKey(key: PkeyInstance; direction: Byte; keyLen: integer; keyMaterial: pchar): integer;
function cipherInit(cipher: PcipherInstance; mode: Byte; IV: pchar): integer;
{sergey has corrected it}
function blocksEnCrypt(cipher: PcipherInstance; key: PkeyInstance; input: PByte;
inputLen: integer; outBuffer: PByte): integer;
{sergey has corrected it}
function blocksDeCrypt(cipher: PcipherInstance; key: PkeyInstance; input: PByte;
inputLen: integer; outBuffer: PByte): integer;
{ cipherUpdateRounds:
Encrypts/Decrypts exactly one full block a specified number of rounds.
Only used in the Intermediate Value Known Answer Test.
Returns:
TRUE - on success
BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) }
function cipherUpdateRounds(cipher: PcipherInstance; key: PkeyInstance; input: PByte;
inputLen: integer; outBuffer: PByte; iRounds: integer): integer;
implementation
{ StrLCopy copies at most MaxLen characters from Source to Dest and returns Dest. }
function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
asm
PUSH EDI
PUSH ESI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
MOV EBX,ECX
XOR AL,AL
TEST ECX,ECX
JZ @@1
REPNE SCASB
JNE @@1
INC ECX
@@1: SUB EBX,ECX
MOV EDI,ESI
MOV ESI,EDX
MOV EDX,EDI
MOV ECX,EBX
SHR ECX,2
REP MOVSD
MOV ECX,EBX
AND ECX,3
REP MOVSB
STOSB
MOV EAX,EDX
POP EBX
POP ESI
POP EDI
end;
function makeKey(key: PkeyInstance; direction: Byte; keyLen: integer; keyMaterial: pchar): integer;
var
k: TArrayK;
i, j, t: integer;
begin
if not assigned(key) then
begin
result:= BAD_KEY_INSTANCE;
exit;
end;
if ((direction = DIR_ENCRYPT) or (direction = DIR_DECRYPT)) then
key.direction:= direction
else
begin
result:= BAD_KEY_DIR;
exit;
end;
if ((keyLen = 128) or (keyLen = 192) or (keyLen = 256)) then
key.keyLen:= keyLen
else
begin
result:= BAD_KEY_MAT;
exit;
end;
if (keyMaterial^ <> #0) then
StrLCopy(key.keyMaterial, keyMaterial, keyLen div 4); // strncpy
{ initialize key schedule: }
for i:= 0 to (key.keyLen div 8)-1 do
begin
t:= integer(key.keyMaterial[2*i]);
if ((t >= ord('0')) and (t <= ord('9'))) then
j:= (t - ord('0')) shl 4
else
if ((t >= ord('a')) and (t <= ord('f'))) then
j:= (t - ord('a') + 10) shl 4
else
if ((t >= ord('A')) and (t <= ord('F'))) then
j:= (t - ord('A') + 10) shl 4
else
begin
result:= BAD_KEY_MAT;
exit;
end;
t:= integer(key.keyMaterial[2*i+1]);
if ((t >= ord('0')) and (t <= ord('9'))) then
j:= j xor (t - ord('0'))
else
if ((t >= ord('a')) and (t <= ord('f'))) then
j:= j xor (t - ord('a') + 10)
else
if ((t >= ord('A')) and (t <= ord('F'))) then
j:= j xor (t - ord('A') + 10)
else
begin
result:= BAD_KEY_MAT;
exit;
end;
k[i mod 4][i div 4]:= word8(j);
end;
rijndaelKeySched(k, key.keyLen, key.blockLen, key.keySched);
result:= rTRUE;
end;
function cipherInit(cipher: PcipherInstance; mode: Byte; IV: pchar): integer;
var
i, j, t: integer;
begin
if ((mode = MODE_ECB) or (mode = MODE_CBC) or (mode = MODE_CFB1)) then
cipher.mode:= mode
else
begin
result:= BAD_CIPHER_MODE;
exit;
end;
if assigned(IV) then
for i:= 0 to (cipher.blockLen div 8)-1 do
begin
t:= integer(IV[2*i]);
if ((t >= ord('0')) and (t <= ord('9'))) then
j:= (t - ord('0')) shl 4
else
if ((t >= ord('a')) and (t <= ord('f'))) then
j:= (t - ord('a') + 10) shl 4
else
if ((t >= ord('A')) and (t <= ord('F'))) then
j:= (t - ord('A') + 10) shl 4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -