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

📄 rijndael_api_ref.pas

📁 Rijndael algorithm修正了CBC下BUG的版本(有源代码)工作在:D5。作者:Sergey Kirichenko。
💻 PAS
📖 第 1 页 / 共 2 页
字号:
            else
              begin
                result:= BAD_CIPHER_INSTANCE;
                exit;
              end;

        t:= integer(IV[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_CIPHER_INSTANCE;
                exit;
              end;
         cipher.IV[i]:= Byte(j);
      end;
  result:= rTRUE;
end;

function blocksEnCrypt(cipher: PcipherInstance; key: PkeyInstance;
                      input: PByte; inputLen: integer; outBuffer: PByte): integer;
var
  i, j, t, numBlocks: integer;
  block: TArrayK;
begin
  { check parameter consistency: }
  if (not assigned(key)) or
      (key.direction <> DIR_ENCRYPT) or
      ((key.keyLen <> 128) and (key.keyLen <> 192) and (key.keyLen <> 256)) then
    begin
      result:= BAD_KEY_MAT;
      exit;
    end;

  if (not assigned(cipher)) or
     ((cipher.mode <> MODE_ECB) and (cipher.mode <> MODE_CBC) and (cipher.mode <> MODE_CFB1)) or
     ((cipher.blockLen <> 128) and (cipher.blockLen <> 192) and (cipher.blockLen <> 256)) then
    begin
      result:= BAD_CIPHER_STATE;
      exit;
    end;

  numBlocks:= inputLen div cipher.blockLen;
  case (cipher.mode) of
    MODE_ECB:
      for i:= 0 to numBlocks-1 do
        begin
          for j:= 0 to (cipher.blockLen div 32)-1 do
            for t:= 0 to 4-1 do
              { parse input stream into rectangular array }
              block[t][j]:= input[4*j+t] and $FF;
          rijndaelEncrypt(block, key.keyLen, cipher.blockLen, key.keySched);
          for j:= 0 to (cipher.blockLen div 32)-1 do
            { parse rectangular array into output ciphertext bytes }
            for t:= 0 to 4-1 do
              outBuffer[4*j+t]:= Byte(block[t][j]);
        end;
    MODE_CBC:
      begin
        for j:= 0 to (cipher.blockLen div 32)-1 do
          for t:= 0 to 4-1 do
            { parse initial value into rectangular array }
            block[t][j]:= cipher.IV[t+4*j] and $FF;
        for i:= 0 to numBlocks-1 do
          begin
            for j:= 0 to (cipher.blockLen div 32)-1 do
              for t:= 0 to 4-1 do
                { parse input stream into rectangular array and exor with
                  IV or the previous ciphertext }
//                block[t][j]:= block[t][j] xor (input[4*j+t] and $FF);                            {!original!}
                block[t][j]:= block[t][j] xor (input[(i*(cipher.blockLen div 8))+4*j+t] and $FF);  {!sergey made it!}
            rijndaelEncrypt(block, key.keyLen, cipher.blockLen, key.keySched);
            for j:= 0 to (cipher.blockLen div 32)-1 do
              { parse rectangular array into output ciphertext bytes }
              for t:= 0 to 4-1 do
//                outBuffer[4*j+t]:= Byte(block[t][j]);                                            {!original!}
                outBuffer[(i*(cipher.blockLen div 8))+4*j+t]:= Byte(block[t][j]);                  {!sergey made it!}
          end;
        end;
    else
      begin
        result:= BAD_CIPHER_STATE;
        exit
      end;
  end;
  result:= numBlocks*cipher.blockLen;
end;

function blocksDeCrypt(cipher: PcipherInstance; key: PkeyInstance; input: PByte;
                      inputLen: integer; outBuffer: PByte): integer;
var
  i, j, t, numBlocks: integer;
  block: TArrayK;
begin
  if (not assigned(cipher)) or
     (not assigned(key)) or
     (key.direction = DIR_ENCRYPT) or
     (cipher.blockLen <> key.blockLen) then
    begin
      result:= BAD_CIPHER_STATE;
      exit;
    end;

  { check parameter consistency: }
  if (not assigned(key)) or
     (key.direction <> DIR_DECRYPT) or
     ((key.keyLen <> 128) and (key.keyLen <> 192) and (key.keyLen <> 256)) then
    begin
      result:= BAD_KEY_MAT;
      exit;
    end;

  if (not assigned(cipher)) or
     ((cipher.mode <> MODE_ECB) and (cipher.mode <> MODE_CBC) and (cipher.mode <> MODE_CFB1)) or
     ((cipher.blockLen <> 128) and (cipher.blockLen <> 192) and (cipher.blockLen <> 256)) then
    begin
      result:= BAD_CIPHER_STATE;
      exit;
    end;

  numBlocks:= inputLen div cipher.blockLen;
  case (cipher.mode) of
    MODE_ECB:
      for i:= 0 to numBlocks-1 do
        begin
          for j:= 0 to (cipher.blockLen div 32)-1 do
            for t:= 0 to 4-1 do
              { parse input stream into rectangular array }
              block[t][j]:= input[4*j+t] and $FF;
          rijndaelDecrypt (block, key.keyLen, cipher.blockLen, key.keySched);
          for j:= 0 to (cipher.blockLen div 32)-1 do
            { parse rectangular array into output ciphertext bytes }
            for t:= 0 to 4-1 do
              outBuffer[4*j+t]:= Byte(block[t][j]);
        end;
    MODE_CBC:
      {! sergey has rearranged processing blocks and
        corrected exclusive-ORing operation !}

      begin
        { blocks after first }
        for i:= numBlocks-1 downto 1 do
          begin
            for j:= 0 to (cipher.blockLen div 32)-1 do
              for t:= 0 to 4-1 do
                { parse input stream into rectangular array }
                block[t][j]:= input[(i*(cipher.blockLen div 8))+ 4*j+ t] and $FF;
            rijndaelDecrypt(block, key.keyLen, cipher.blockLen, key.keySched);

            for j:= 0 to (cipher.blockLen div 32)-1 do
              { exor previous ciphertext block and parse rectangular array
                into output ciphertext bytes }
              for t:= 0 to 4-1 do
                outBuffer[(i*(cipher.blockLen div 8))+ 4*j+t]:= Byte(block[t][j] xor
                           input[(i-1)*(cipher.blockLen div 8)+ 4*j+ t]);
          end;

        { first block }
        for j:= 0 to (cipher.blockLen div 32)-1 do
          for t:= 0 to 4-1 do
            { parse input stream into rectangular array }
            block[t][j]:= input[4*j+t] and $FF;
        rijndaelDecrypt(block, key.keyLen, cipher.blockLen, key.keySched);

        for j:= 0 to (cipher.blockLen div 32)-1 do
          { exor the IV and parse rectangular array into output ciphertext bytes }
          for t:= 0 to 4-1 do
            outBuffer[4*j+t]:= Byte(block[t][j] xor cipher.IV[t+4*j]);
      end;
    else
      begin
        result:= BAD_CIPHER_STATE;
        exit;
      end;
  end;
  result:= numBlocks*cipher.blockLen;
end;

function cipherUpdateRounds(cipher: PcipherInstance; key: PkeyInstance; input: PByte;
                            inputLen: integer; outBuffer: PByte; iRounds: integer): integer;
var
  j, t: integer;
  block: TArrayK;
begin
  if (not assigned(cipher)) or
     (not assigned(key)) or
     (cipher.blockLen <> key.blockLen) then
    begin
      result:= BAD_CIPHER_STATE;
      exit;
    end;

  for j:= 0 to (cipher.blockLen div 32)-1 do
    for t:= 0 to 4-1 do
      { parse input stream into rectangular array }
      block[t][j]:= input[4*j+t] and $FF;

  case (key.direction) of
    DIR_ENCRYPT:
      rijndaelEncryptRound(block, key.keyLen, cipher.blockLen, key.keySched, irounds);
    DIR_DECRYPT:
      rijndaelDecryptRound(block, key.keyLen, cipher.blockLen, key.keySched, irounds);
    else
      begin
        result:= BAD_KEY_DIR;
        exit;
      end;
  end;

  for j:= 0 to (cipher.blockLen div 32)-1 do
    { parse rectangular array into output ciphertext bytes }
    for t:= 0 to 4-1 do
      outBuffer[4*j+t]:= Byte(block[t][j]);
  result:= rTRUE;
end;


end.

⌨️ 快捷键说明

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