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

📄 aes.pas

📁 这个程序的主要目的是为了提供一个具有通用性的 AVR Bootloader
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  i: Byte;
  Rcon: array[0..3] of Byte; // Round constant.
  key: PByte;
begin
  Rcon[0] := 1;
  Rcon[1] := 0;
  Rcon[2] := 0;
  Rcon[3] := 0;

  key := @kTable;

  // Copy key to start of expanded key.
  {i := KEYLENGTH;
  repeat
    expandedKey^[0] := key^;
    inc(PByte(expandedKey), 1);
    inc(key, 1);
    i := i - 1;
  until (i = 0);}
  CopyBytes(expandedKey, PByteArray(key), KEYLENGTH);
  Inc(PByte(expandedKey), KEYLENGTH);

  // Prepare last 4 bytes of key in temp.
  dec(PByte(expandedKey), 4);
  temp[0] := expandedKey^[0];
  temp[1] := expandedKey^[1];
  temp[2] := expandedKey^[2];
  temp[3] := expandedKey^[3];
  Inc(PByte(expandedKey), 4);

  // Expand key.
  i := KEYLENGTH;
  while (i < BLOCKSIZE * (ROUNDS + 1)) do
  begin
    if KEYLENGTH > 24 then
    begin
      // Are we at the start of a multiple of the key size?
      if ((i mod KEYLENGTH) = 0) then
      begin
        CycleLeft(@temp); // Cycle left once.
        SubBytes(@temp, 4); // Substitute each byte.
        XORBytes(@temp, @Rcon, 4); // Add constant in GF(2).
        Rcon[0] := CalcDat(Rcon[0]);

        // Keysize larger than 24 bytes, ie. larger that 192 bits?
      end
        // Are we right past a block size?
      else
        if ((i mod KEYLENGTH) = BLOCKSIZE) then
          SubBytes(@temp, 4); // Substitute each byte.
    end
    else
    begin
      if ((i mod KEYLENGTH) = 0) then
      begin
        CycleLeft(@temp); // Cycle left once.
        SubBytes(@temp, 4); // Substitute each byte.
        XORBytes(@temp, @Rcon, 4); // Add constant in GF(2).
        Rcon[0] := CalcDat(Rcon[0]);
      end;
    end;

    // Add bytes in GF(2) one KEYLENGTH away.
    dec(PByte(expandedKey), KEYLENGTH);
    XORBytes(@temp, expandedKey, 4);
    Inc(PByte(expandedKey), KEYLENGTH);

    // Copy result to current 4 bytes.
    {expandedKey[0] := temp[0];
    expandedKey[1] := temp[1];
    expandedKey[2] := temp[2];
    expandedKey[3] := temp[3];}
    CopyBytes(expandedKey, @temp, 4);
    Inc(PByte(expandedKey), 4);
    i := i + 4; // Next 4 bytes.
  end;
end;

procedure InvCipher(block, expandedKey: PByteArray);
var
  round: Byte;
begin
  round := ROUNDS - 1;
  Inc(PByte(expandedKey), BLOCKSIZE * ROUNDS);

  XORBytes(block, expandedKey, 16);
  dec(PByte(expandedKey), BLOCKSIZE);

  repeat
    InvShiftRows(block);
    InvSubBytesAndXOR(block, expandedKey, 16);
    dec(PByte(expandedKey), BLOCKSIZE);
    InvMixColumns(block);
    round := round - 1;
  until (round = 0);

  InvShiftRows(block);
  InvSubBytesAndXOR(block, expandedKey, 16);
end;

procedure aesDecInit;
var
  i: Integer;
begin
  powTbl := @block1;
  logTbl := @block2;
  CalcPowLog(powTbl, logTbl);

  sBox := @tempbuf;
  CalcSBox(sBox);

  expandedKey := @block1;
  KeyExpansion(expandedKey);

  sBoxInv := @block2; // Must be block2.
  CalcSBoxInv(sBox, sBoxInv);
  for i := 0 to 15 do
    chainCipherBlock[i] := 0;
end;

procedure aesDecrypt(buffer, chainBlock: PByteArray);
var
  temp: array[0..BLOCKSIZE - 1] of Byte;
begin
  CopyBytes(@temp, buffer, BLOCKSIZE);
  InvCipher(buffer, expandedKey);
  XORBytes(buffer, chainBlock, BLOCKSIZE);
  CopyBytes(chainBlock, @temp, BLOCKSIZE);
end;

function Multiply(num, factor: Byte): Byte;
var
  mask: Byte;
begin
  mask := 1;
  Result := 0;
  while (mask <> 0) do
  begin
    // Check bit of factor given by mask.
    if ((mask and factor) <> 0) then
    begin
      // Add current multiple of num in GF(2).
      Result := Result xor num;
    end;

    // Shift mask to indicate next bit.
    mask := mask shl 1;

    // Double num.
    num := CalcDat(num);
  end;
end;

function DotProduct(vector1, vector2: PByteArray): Byte;
begin
  Result := 0;
  Result := Result xor Multiply(vector1^[0], vector2^[0]);
  Inc(PByte(vector1));
  Inc(PByte(vector2));
  Result := Result xor Multiply(vector1^[0], vector2^[0]);
  Inc(PByte(vector1));
  Inc(PByte(vector2));
  Result := Result xor Multiply(vector1^[0], vector2^[0]);
  Inc(PByte(vector1));
  Inc(PByte(vector2));
  Result := Result xor Multiply(vector1^[0], vector2^[0]);
end;

procedure MixColumn(column: PByteArray);
var
  // Prepare first row of matrix twice, to eliminate need for cycling.
  row: array[0..7] of Byte;
  Result: array[0..3] of Byte;
begin
  row[0] := $02;
  row[1] := $03;
  row[2] := $01;
  row[3] := $01;
  row[4] := $02;
  row[5] := $03;
  row[6] := $01;
  row[7] := $01;

  // Take dot products of each matrix row and the column vector.
  Result[0] := DotProduct(@row[0], column);
  Result[1] := DotProduct(@row[3], column);
  Result[2] := DotProduct(@row[2], column);
  Result[3] := DotProduct(@row[1], column);

  // Copy temporary result to original column.
  column^[0] := Result[0];
  column^[1] := Result[1];
  column^[2] := Result[2];
  column^[3] := Result[3];
end;

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

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

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

  // Cycle third row left 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 left three times, ie. right once.
  temp := state^[3 + 3 * 4];
  state^[3 + 3 * 4] := state^[3 + 2 * 4];
  state^[3 + 2 * 4] := state^[3 + 1 * 4];
  state^[3 + 1 * 4] := state^[3 + 0 * 4];
  state^[3 + 0 * 4] := temp;
end;

procedure Cipher(block, expandedKey: PByteArray);
var
  round: Byte;
begin
  round := ROUNDS - 1;
  XORBytes(block, expandedKey, 16);
  Inc(PByte(expandedKey), BLOCKSIZE);

  repeat
    SubBytes(block, 16);
    ShiftRows(block);
    MixColumns(block);
    XORBytes(block, expandedKey, 16);
    Inc(PByte(expandedKey), BLOCKSIZE);
    round := round - 1;
  until (round = 0);

  SubBytes(block, 16);
  ShiftRows(block);
  XORBytes(block, expandedKey, 16);
end;

procedure aesEncInit;
var
  i: Integer;
begin
  powTbl := @block1;
  logTbl := @tempbuf;
  CalcPowLog(powTbl, logTbl);

  sBox := @block2;
  CalcSBox(sBox);

  expandedKey := @block1;
  KeyExpansion(expandedKey);

  for i := 0 to 15 do
    chainCipherBlock[i] := 0;
end;

procedure aesEncrypt(buffer, chainBlock: PByteArray);
begin
  XORBytes(buffer, chainBlock, BLOCKSIZE);
  Cipher(buffer, expandedKey);
  CopyBytes(chainBlock, buffer, BLOCKSIZE);
end;

procedure aesEncBlock(buffer: PByteArray; key:PByteArray; Len: Integer; mode: Integer);
var
  i: Integer;
begin
  aesMode(mode);
  aesKey(key);
  aesEncInit;

  i := 0;
  while i <= (Len - 16) do
  begin
    aesEncrypt(@buffer^[i], @chainCipherBlock);
    i := i + 16;
  end;
end;

procedure aesDecBlock(buffer: PByteArray; key:PByteArray; Len: Integer; mode: Integer);
var
  i: Integer;
begin
  aesMode(mode);
  aesKey(key);
  aesDecInit;

  i := 0;
  while i <= (Len - 16) do
  begin
    aesDecrypt(@buffer^[i], @chainCipherBlock);
    i := i + 16;
  end;
end;

initialization
  aesMode(128);
finalization

end.

⌨️ 快捷键说明

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