⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rijndael_api_ref.pas

📁 Rijndael algorithm修正了CBC下BUG的版本(有源代码)工作在:D5。作者:Sergey Kirichenko。
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{* 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 + -