Closed adezxc closed 7 months ago
with Util.Encoders.AES;
with Util.Streams;
with Util.Streams.Files;
with Util.Streams.AES;
with Util.Encoders;
with Ada.Command_Line;
with Text_IO; use Text_IO;
with Ada.Characters.Handling;
with Ada.Streams.Stream_IO;
with Util.Streams.Texts;
procedure Ada_Aes is
use Ada.Command_Line;
function Base32_Encode (S : String) return String is
use Util.Encoders;
C : constant Encoder := Util.Encoders.Create ("base32");
begin
return C.Encode ((S));
end Base32_Encode;
function Base32_Decode (S : String) return String is
use Ada.Characters.Handling;
use Util.Encoders;
D : constant Decoder := Util.Encoders.Create ("base32");
begin
return D.Decode (To_Upper (S));
end Base32_Decode;
procedure Decrypt_File (Source : String; Destination : String; Key : String)
is
In_Stream : aliased Util.Streams.Files.File_Stream;
Out_Stream : aliased Util.Streams.Files.File_Stream;
Decipher : aliased Util.Streams.AES.Decoding_Stream;
Password_Key :
constant Util.Encoders.Secret_Key
(Length => Util.Encoders.AES.AES_128_Length) :=
Util.Encoders.Create (Base32_Decode (Key));
begin
In_Stream.Open (Ada.Streams.Stream_IO.In_File, Source);
Out_Stream.Create
(Mode => Ada.Streams.Stream_IO.Out_File, Name => Destination);
Decipher.Produces
(Output => Out_Stream'Unchecked_Access, Size => 65_536);
Decipher.Set_Key (Secret => Password_Key, Mode => Util.Encoders.AES.CTR);
Util.Streams.Copy (From => In_Stream, Into => Decipher);
end Decrypt_File;
procedure Encrypt_File (Source : String; Destination : String; Key : String)
is
In_Stream : aliased Util.Streams.Files.File_Stream;
Out_Stream : aliased Util.Streams.Files.File_Stream;
Cipher : aliased Util.Streams.AES.Encoding_Stream;
Password_Key :
constant Util.Encoders.Secret_Key
(Length => Util.Encoders.AES.AES_128_Length) :=
Util.Encoders.Create (Base32_Decode (Key));
begin
In_Stream.Open (Ada.Streams.Stream_IO.In_File, Source);
Out_Stream.Create
(Mode => Ada.Streams.Stream_IO.Out_File, Name => Destination);
Cipher.Produces (Output => Out_Stream'Unchecked_Access, Size => 65_536);
Cipher.Set_Key (Secret => Password_Key, Mode => Util.Encoders.AES.CTR);
Util.Streams.Copy (From => In_Stream, Into => Cipher);
end Encrypt_File;
begin
if Argument_Count /= 4 then
Put_Line ("Correct usage:");
Put_Line
(Ada.Command_Line.Command_Name &
" encode input.dat output.dat <base32encodedkey>");
Put_Line
(Ada.Command_Line.Command_Name &
" decode input.dat output.dat <base32encodedkey>");
return;
end if;
declare
Cipher_Mode : String := Argument (1);
Input_File : String := Argument (2);
Output_File : String := Argument (3);
Key : String := Argument (4);
begin
if Cipher_Mode = "encode" then
Encrypt_File
(Source => Input_File, Destination => Output_File, Key => Key);
return;
end if;
if Cipher_Mode = "decode" then
Decrypt_File
(Source => Input_File, Destination => Output_File, Key => Key);
return;
end if;
Put_Line ("Unrecognized function");
return;
end;
end Ada_Aes;
Thanks to have found that issue!
CFB encryption has the same issue.
The unit tests are wrong and don't test correctly the CFB, OFB and CTR modes.
The tests in regtests/util-streams-tests.adb instantiate a generic procedure with the encryption mode but for the CFB, OFB and CTR tests, they are instantiated with AEC.PCBC mode!!!!!
Fixing these tests, raises the issue!
Utilada version: 2.6.0
I have a simple utility that should be able to encrypt and decrypt files in AES-CTR 128Bit mode, but it fails and returns this
CONSTRAINT_ERROR
.With some debugging, it seems that it manages to go through one 4KB data block, then
Offset
is set to15
and DataLast index is
16`, so it tries to access a non-existent elementI will add the program's source code in the comment