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

📄 aes.pas

📁 这个程序的主要目的是为了提供一个具有通用性的 AVR Bootloader
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{
  Project:  AVR Universal Bootloader Download
  File:     PC1.pas
  Describe: AES crypt algorithm pascal unit
            base on AVR231's aes code
            128/256 bits key
  Author:   Shaoziyang
  Date:     2008.6
  Version:  1.0
  Web:      http://shaoziyang.googlepages.com
        or  http://shaoziyang.bloger.com.cn (Chinese)
  Email:    shaoziyang@gmail.com
}

unit aes;

interface

uses
  SysUtils;

const
  //!< Lower 8 bits of (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1).
  BPOLY = $1B;

  //!< Block size in number of bytes.
  BLOCKSIZE = 16;

procedure aesMode(key: Integer);
procedure aesKey(key: PByteArray);
procedure aesEncInit;
procedure aesEncrypt(buffer, chainBlock: PByteArray);
procedure aesDecInit;
procedure aesDecrypt(buffer, chainBlock: PByteArray);
procedure aesEncBlock(buffer: PByteArray; key:PByteArray; Len: Integer; mode: Integer=128);
procedure aesDecBlock(buffer: PByteArray; key:PByteArray; Len: Integer; mode: Integer=128);

implementation

var
  kTable: array[0..31] of Byte =
  (
    $D0, $94, $3F, $8C, $29, $76, $15, $D8,
    $20, $40, $E3, $27, $45, $D8, $48, $AD,
    $EA, $8B, $2A, $73, $16, $E9, $B0, $49,
    $45, $B3, $39, $28, $0A, $C3, $28, $3C
    );

  block1: array[0..255] of Byte; //!< Workspace 1.
  block2: array[0..255] of Byte; //!< Worksapce 2.
  tempbuf: array[0..255] of Byte;
  chainCipherBlock: array[0..15] of Byte;

  powTbl: PByteArray; //!< Final location of exponentiation lookup table.
  logTbl: PByteArray; //!< Final location of logarithm lookup table.
  sBox: PByteArray; //!< Final location of s-box.
  sBoxInv: PByteArray; //!< Final location of inverse s-box.
  expandedKey: PByteArray; //!< Final location of expanded key.

  ROUNDS: Byte = 10; //!< Number of rounds.
  KEYLENGTH: Byte = 16; //!< Key length in number of bytes.

procedure aesMode(key: Integer);
begin
  if key <= 128 then
  begin
    ROUNDS := 10;
    KEYLENGTH := 16;
  end
  else
  begin
    ROUNDS := 14;
    KEYLENGTH := 32;
  end;
end;

procedure aesKey(key: PByteArray);
var
  i: Integer;
begin
  for i := 0 to KEYLENGTH - 1 do
    kTable[i] := key^[i];
end;

function CalcDat(t: Byte): Byte;
begin
  if (t and $80) = $80 then
    Result := ((t * 2) xor BPOLY)
  else
    Result := (t * 2);
end;

procedure CalcPowLog(powTbl, logTbl: PByteArray);
var
  i, t: Byte;
begin
  i := 0;
  t := 1;
  repeat
    // Use 0x03 as root for exponentiation and logarithms.
    powTbl^[i] := t;
    logTbl^[t] := i;
    i := i + 1;

    // Muliply t by 3 in GF(2^8).
    t := t xor CalcDat(t);
  until (t = 1); // Cyclic properties ensure that i < 255.

  powTbl^[255] := powTbl^[0]; // 255 = '-0', 254 = -1, etc.
end;

procedure CalcSBox(sBox: PByteArray);
var
  i, rot: Byte;
  temp: Byte;
  Result: Byte;
begin
  // Fill all entries of sBox[].
  i := 0;
  repeat
    //Inverse in GF(2^8).
    if (i > 0) then
    begin
      temp := powTbl^[255 - logTbl^[i]];
    end
    else
    begin
      temp := 0;
    end;

    // Affine transformation in GF(2).
    Result := temp xor $63; // Start with adding a vector in GF(2).
    for rot := 1 to 4 do
    begin
      // Rotate left.
      temp := (temp shl 1) or (temp shr 7);

      // Add rotated byte in GF(2).
      Result := Result xor temp;
    end;

    // Put result in table.
    sBox^[i] := Result;
    i := i + 1;
  until (i = 0);
end;

procedure CalcSBoxInv(sBox, sBoxInv: PByteArray);
var
  i, j: Byte;
begin
  i := 0;
  j := 0;
  // Iterate through all elements in sBoxInv using  i.
  repeat

    // Search through sBox using j.
    repeat
      // Check if current j is the inverse of current i.
      if (sBox^[j] = i) then
      begin
        // If so, set sBoxInc and indicate search finished.
        sBoxInv^[i] := j;
        j := 255;
      end;
      j := j + 1;
    until (j = 0);
    i := i + 1;
  until (i = 0);
end;

procedure CycleLeft(row: PByteArray);
var
  temp: Byte;
begin
  // Cycle 4 bytes in an array left once.
  temp := row^[0];
  row^[0] := row^[1];
  row^[1] := row^[2];
  row^[2] := row^[3];
  row^[3] := temp;
end;

procedure InvMixColumn(column: PByteArray);
var
  r0, r1, r2, r3: Byte;
begin

  r0 := column^[1] xor column^[2] xor column^[3];
  r1 := column^[0] xor column^[2] xor column^[3];
  r2 := column^[0] xor column^[1] xor column^[3];
  r3 := column^[0] xor column^[1] xor column^[2];

  column^[0] := CalcDat(column^[0]);
  column^[1] := CalcDat(column^[1]);
  column^[2] := CalcDat(column^[2]);
  column^[3] := CalcDat(column^[3]);

  r0 := r0 xor column^[0] xor column^[1];
  r1 := r1 xor column^[1] xor column^[2];
  r2 := r2 xor column^[2] xor column^[3];
  r3 := r3 xor column^[0] xor column^[3];

  column^[0] := CalcDat(column^[0]);
  column^[1] := CalcDat(column^[1]);
  column^[2] := CalcDat(column^[2]);
  column^[3] := CalcDat(column^[3]);

  r0 := r0 xor column^[0] xor column^[2];
  r1 := r1 xor column^[1] xor column^[3];
  r2 := r2 xor column^[0] xor column^[2];
  r3 := r3 xor column^[1] xor column^[3];

  column^[0] := CalcDat(column^[0]);
  column^[1] := CalcDat(column^[1]);
  column^[2] := CalcDat(column^[2]);
  column^[3] := CalcDat(column^[3]);

  column^[0] := column^[0] xor column^[1] xor column^[2] xor column^[3];
  r0 := r0 xor column^[0];
  r1 := r1 xor column^[0];
  r2 := r2 xor column^[0];
  r3 := r3 xor column^[0];

  column^[0] := r0;
  column^[1] := r1;
  column^[2] := r2;
  column^[3] := r3;
end;

procedure SubBytes(bytes: PByteArray; count: Byte);
var
  i: Byte;
begin
  i := 0;
  repeat
    bytes^[i] := sBox^[bytes^[i]]; // Substitute every byte in state.
    i := i + 1;
    count := count - 1;
  until (count = 0);
end;

procedure InvSubBytesAndXOR(bytes, key: PByteArray; count: Byte);
var
  i: Byte;
begin
  i := 0;
  repeat
    // *bytes = sBoxInv[ *bytes ] ^ *key; // Inverse substitute every byte in state and add key.
    bytes^[i] := block2[bytes^[i]] xor key^[i]; // Use block2 directly. Increases speed.
    i := i + 1;
    count := count - 1;
  until (count = 0);
end;

procedure InvShiftRows(state: PByteArray);
var
  temp: Byte;
begin
  // Note: State is arranged column by column.

  // Cycle second row right one time.
  temp := state^[1 + 3 * 4];
  state^[1 + 3 * 4] := state^[1 + 2 * 4];
  state^[1 + 2 * 4] := state^[1 + 1 * 4];
  state^[1 + 1 * 4] := state^[1 + 0 * 4];
  state^[1 + 0 * 4] := temp;

  // Cycle third row right two times.
  temp := state^[2 + 0 * 4];
  state^[2 + 0 * 4] := state^[2 + 2 * 4];
  state^[2 + 2 * 4] := temp;
  temp := state^[2 + 1 * 4];
  state^[2 + 1 * 4] := state^[2 + 3 * 4];
  state^[2 + 3 * 4] := temp;

  // Cycle fourth row right three times, ie. left once.
  temp := state^[3 + 0 * 4];
  state^[3 + 0 * 4] := state^[3 + 1 * 4];
  state^[3 + 1 * 4] := state^[3 + 2 * 4];
  state^[3 + 2 * 4] := state^[3 + 3 * 4];
  state^[3 + 3 * 4] := temp;
end;

procedure InvMixColumns(state: PByteArray);
begin
  InvMixColumn(@state[0 * 4]);
  InvMixColumn(@state[1 * 4]);
  InvMixColumn(@state[2 * 4]);
  InvMixColumn(@state[3 * 4]);
end;

procedure XORBytes(bytes1, bytes2: PByteArray; count: Byte);
var
  i: Integer;
begin
  i := 0;
  repeat
    bytes1^[i] := bytes1^[i] xor bytes2^[i]; // Add in GF(2), ie. XOR.
    i := i + 1;
    count := count - 1;
  until (count = 0);
end;

procedure CopyBytes(a, b: PByteArray; count: Byte);
var
  i: Byte;
begin
  i := 0;
  repeat
    a^[i] := b^[i];
    i := i + 1;
    count := count - 1;
  until (count = 0);
end;

procedure KeyExpansion(expandedKey: PByteArray);
var
  temp: array[0..3] of Byte;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -