raw
smg_comms_rsa_oaep      1  --S.MG, 2018
smg_comms_rsa_oaep 2
smg_comms_rsa_oaep 3 with Interfaces; use Interfaces;
smg_comms_rsa_oaep 4 with Interfaces.C; use Interfaces.C;
smg_comms_80cols 5 with Ada.Text_IO; use Ada.Text_IO;
smg_comms_rsa_oaep 6 with RSA_OAEP; use RSA_OAEP;
smg_comms_rsa_oaep 7 with OAEP; use OAEP;
smg_comms_rsa_oaep 8 with Raw_Types; use Raw_Types;
smg_comms_rsa_oaep 9 with RNG; use RNG;
smg_comms_rsa_oaep 10 with Keccak; use Keccak;
smg_comms_io_rsa_... 11 with IO_RSA;
smg_comms_rsa_oaep 12
smg_comms_rsa_oaep 13 package body Test_RSA_OAEP is
smg_comms_rsa_oaep 14
smg_comms_rsa_oaep 15 procedure test_char_array is
smg_comms_rsa_oaep 16 S : String := OAEP.TMSR_STR;
smg_comms_packing... 17 O : Octets := Raw_Types.OAEP_RESERVED;
smg_comms_rsa_oaep 18 A : char_array(0..O'Length-1) := (others => '0');
smg_comms_rsa_oaep 19 B : Octets(0..O'Length -1) := (others => 0);
smg_comms_rsa_oaep 20 Fail : Boolean := FALSE;
smg_comms_rsa_oaep 21 begin
smg_comms_rsa_oaep 22 Octets_To_Char_Array(O, A);
smg_comms_rsa_oaep 23 Char_Array_To_Octets(A, B);
smg_comms_rsa_oaep 24
smg_comms_rsa_oaep 25 if B /= O then
smg_comms_rsa_oaep 26 Put_Line("FAIL: char_array_to_octets");
smg_comms_rsa_oaep 27 else
smg_comms_rsa_oaep 28 Put_Line("PASS: char_array_to_octets");
smg_comms_rsa_oaep 29 end if;
smg_comms_rsa_oaep 30
smg_comms_rsa_oaep 31 for I in 0..S'Length-1 loop
smg_comms_rsa_oaep 32 declare
smg_comms_rsa_oaep 33 C : Character := Character(A(A'First + size_t(I)));
smg_comms_rsa_oaep 34 E : Character := S(S'First + I);
smg_comms_rsa_oaep 35 begin
smg_comms_rsa_oaep 36 if C /= E then
smg_comms_rsa_oaep 37 Fail := TRUE;
smg_comms_rsa_oaep 38 Put("Error at pos " & Integer'Image(I) & ": ");
smg_comms_rsa_oaep 39 Put(Integer'Image(Character'Pos(C)));
smg_comms_rsa_oaep 40 Put_Line(" instead of " & Integer'Image(Character'Pos(E)));
smg_comms_rsa_oaep 41 end if;
smg_comms_rsa_oaep 42 end;
smg_comms_rsa_oaep 43 end loop;
smg_comms_rsa_oaep 44 if FAIL then
smg_comms_rsa_oaep 45 Put_Line("FAIL: test octets_to_char_array");
smg_comms_rsa_oaep 46 else
smg_comms_rsa_oaep 47 Put_Line("PASS: test octets_to_char_array");
smg_comms_rsa_oaep 48 end if;
smg_comms_rsa_oaep 49 end test_char_array;
smg_comms_rsa_oaep 50
smg_comms_rsa_oaep 51 -- test OAEP encrypt + decrypt
smg_comms_rsa_oaep 52 procedure test_oaep is
smg_comms_rsa_oaep 53 Plain: Octets(1..MAX_LEN_MSG);
smg_comms_rsa_oaep 54 Short: Octets(0..10);
smg_comms_rsa_oaep 55 Encr : OAEP_Block;
smg_comms_rsa_oaep 56 Decr : OAEP_HALF;
smg_comms_rsa_oaep 57 Len : Natural;
smg_comms_rsa_oaep 58 Entropy: OAEP_Block;
smg_comms_rsa_oaep 59 Success : Boolean;
smg_comms_rsa_oaep 60 begin
smg_comms_rsa_oaep 61 RNG.Get_Octets(Plain);
smg_comms_rsa_oaep 62 RNG.Get_Octets(Entropy);
smg_comms_rsa_oaep 63 RNG.Get_Octets(Short);
smg_comms_rsa_oaep 64
smg_comms_rsa_oaep 65 -- test full length message
smg_comms_rsa_oaep 66 OAEP_Encrypt(Plain, Entropy, Encr);
smg_comms_rsa_oaep 67 OAEP_Decrypt(Encr, Len, Decr, Success);
smg_comms_rsa_oaep 68
smg_comms_rsa_oaep 69 if not Success or Len/8 /= Plain'Length then
smg_comms_rsa_oaep 70 Put_Line("FAIL: oaep encrypt/decrypt on max len message.");
smg_comms_rsa_oaep 71 else
smg_comms_rsa_oaep 72 if Decr(Decr'First..Decr'First+Len/8-1) /=
smg_comms_rsa_oaep 73 Plain(Plain'First..Plain'First+Len/8-1) then
smg_comms_rsa_oaep 74 Put_Line("FAIL: oaep encrypt/decrypt on max len message - " &
smg_comms_rsa_oaep 75 "result different from expected.");
smg_comms_rsa_oaep 76 else
smg_comms_rsa_oaep 77 Put_Line("PASS: oaep encrypt/decrypt on max len message.");
smg_comms_rsa_oaep 78 end if;
smg_comms_rsa_oaep 79 end if;
smg_comms_rsa_oaep 80
smg_comms_rsa_oaep 81 -- test short message
smg_comms_rsa_oaep 82 OAEP_Encrypt(Short, Entropy, Encr);
smg_comms_rsa_oaep 83 OAEP_Decrypt(Encr, Len, Decr, Success);
smg_comms_rsa_oaep 84 if not Success or Len/8 /= Short'Length then
smg_comms_rsa_oaep 85 Put_Line("FAIL: oaep encrypt/decrypt on short message.");
smg_comms_rsa_oaep 86 else
smg_comms_rsa_oaep 87 if Decr(Decr'First..Decr'First+Len/8-1) /=
smg_comms_rsa_oaep 88 Short(Short'First..Short'First+Len/8-1) then
smg_comms_rsa_oaep 89 Put_Line("FAIL: oaep encrypt/decrypt on short message - " &
smg_comms_rsa_oaep 90 "result different from expected.");
smg_comms_rsa_oaep 91 else
smg_comms_rsa_oaep 92 Put_Line("PASS: oaep encrypt/decrypt on short message.");
smg_comms_rsa_oaep 93 end if;
smg_comms_rsa_oaep 94 end if;
smg_comms_rsa_oaep 95
smg_comms_rsa_oaep 96 end test_oaep;
smg_comms_rsa_oaep 97
smg_comms_rsa_oaep 98 -- test JUST RSA (i.e. without oaep) with RSA key pair previously generated
smg_comms_shorter_e 99 procedure test_rsa( E_Len : in Positive;
smg_comms_shorter_e 100 D_Len : in Positive;
smg_comms_shorter_e 101 Filename : in String) is
smg_comms_rsa_oaep 102 Plain: OAEP_Block := (others => 0);
smg_comms_rsa_oaep 103 Decr : OAEP_Block := (others => 0);
smg_comms_rsa_oaep 104 Encr : RSA_len;
smg_comms_rsa_oaep 105 pkey: RSA_pkey;
smg_comms_rsa_oaep 106 skey: RSA_skey;
smg_comms_rsa_oaep 107 begin
smg_comms_rsa_oaep 108 -- initialize with RSA pair previously generated
smg_comms_shorter_e 109 IO_RSA.ReadRSAKey( Filename, E_Len, D_Len, skey );
smg_comms_80cols 110
smg_comms_rsa_oaep 111 -- copy n and e for public key
smg_comms_rsa_oaep 112 pkey.n := skey.n;
smg_comms_rsa_oaep 113 pkey.e := skey.e;
smg_comms_rsa_oaep 114 -- get random data
smg_comms_rsa_oaep 115 RNG.Get_Octets(Plain);
smg_comms_rsa_oaep 116 -- make first octet < RSA key's modulus first octet
smg_comms_rsa_oaep 117 Plain(Plain'First) := 16#00#;
smg_comms_rsa_oaep 118 -- naked rsa encrypt/decrypt
smg_comms_shorter_e 119 Put_Line("Encrypting with RSA public key with e len " &
smg_comms_shorter_e 120 Positive'Image(E_Len) & "...");
smg_comms_rsa_oaep 121 Public_RSA( Plain, pkey, Encr );
smg_comms_shorter_e 122 Put_Line("Decrypting with RSA private key...");
smg_comms_rsa_oaep 123 Private_RSA( Encr, skey, Decr );
smg_comms_shorter_e 124 Put_Line("Checking...");
smg_comms_rsa_oaep 125
smg_comms_rsa_oaep 126 -- check result
smg_comms_rsa_oaep 127 if Decr /= Plain then
smg_comms_rsa_oaep 128 Put_Line("FAIL: RSA encrypt/decrypt result doesn't match plain.");
smg_comms_rsa_oaep 129 else
smg_comms_rsa_oaep 130 Put_Line("PASS: RSA encrypt/decrypt");
smg_comms_rsa_oaep 131 end if;
smg_comms_rsa_oaep 132 end test_rsa;
smg_comms_rsa_oaep 133
smg_comms_rsa_oaep 134 -- test rsa+oaep with RSA key pair previously generated
smg_comms_rsa_oaep 135 procedure test_rsa_oaep is
smg_comms_rsa_oaep 136 Plain: Octets(1..MAX_LEN_MSG) := (others=>20);
smg_comms_rsa_oaep 137 Short: Octets(1..10);
smg_comms_rsa_oaep 138 Decr : RSA_len;
smg_comms_rsa_oaep 139 Encr : RSA_len;
smg_comms_rsa_oaep 140 pkey: RSA_pkey;
smg_comms_rsa_oaep 141 skey: RSA_skey;
smg_comms_rsa_oaep 142 Success: Boolean;
smg_comms_rsa_oaep 143 Len : Natural;
smg_comms_rsa_oaep 144 begin
smg_comms_rsa_oaep 145 -- initialize with RSA pair previously generated
smg_comms_shorter_e 146 IO_RSA.ReadRSAKey( "keys_rsa.txt", Raw_Types.RSA_KEY_OCTETS,
smg_comms_shorter_e 147 Raw_Types.RSA_KEY_OCTETS*2, skey );
smg_comms_rsa_oaep 148 -- copy n and e for public key
smg_comms_rsa_oaep 149 pkey.n := skey.n;
smg_comms_rsa_oaep 150 pkey.e := skey.e;
smg_comms_rsa_oaep 151
smg_comms_rsa_oaep 152 -- test with 0 message of length Plain'Length
smg_comms_rsa_oaep 153 RSA_OAEP.Encrypt(Plain, pkey, Encr);
smg_comms_rsa_oaep 154 RSA_OAEP.Decrypt(Encr, skey, Decr, Len, Success);
smg_comms_rsa_oaep 155 if (not Success) or Len /= Plain'Length
smg_comms_rsa_oaep 156 or Plain /= Decr(Decr'First..Decr'First+Plain'Length-1) then
smg_comms_rsa_oaep 157 Put_Line("FAIL: RSA_OAEP on max len message 20-filled.");
smg_comms_rsa_oaep 158 else
smg_comms_rsa_oaep 159 Put_Line("PASS: RSA_OAEP on max len message 20-filled.");
smg_comms_rsa_oaep 160 end if;
smg_comms_rsa_oaep 161
smg_comms_rsa_oaep 162 -- get random data for "plain" message
smg_comms_rsa_oaep 163 RNG.Get_Octets(Plain);
smg_comms_rsa_oaep 164 RSA_OAEP.Encrypt(Plain, pkey, Encr);
smg_comms_rsa_oaep 165 RSA_OAEP.Decrypt(Encr, skey, Decr, Len, Success);
smg_comms_rsa_oaep 166 if (not Success) or Len /= Plain'Length
smg_comms_rsa_oaep 167 or Plain /= Decr(Decr'First..Decr'First+Plain'Length-1) then
smg_comms_rsa_oaep 168 Put_Line("FAIL: RSA_OAEP on random data of max length.");
smg_comms_rsa_oaep 169 else
smg_comms_rsa_oaep 170 Put_Line("PASS: RSA_OAEP on random data of max length.");
smg_comms_rsa_oaep 171 end if;
smg_comms_rsa_oaep 172
smg_comms_rsa_oaep 173 -- get random data for "short" message
smg_comms_rsa_oaep 174 RNG.Get_Octets(Short);
smg_comms_rsa_oaep 175 RSA_OAEP.Encrypt(Short, pkey, Encr);
smg_comms_rsa_oaep 176 RSA_OAEP.Decrypt(Encr, skey, Decr, Len, Success);
smg_comms_rsa_oaep 177 if (not Success) or Len /= Short'Length
smg_comms_rsa_oaep 178 or Short /= Decr(Decr'First..Decr'First+Short'Length-1) then
smg_comms_rsa_oaep 179 Put_Line("FAIL: RSA_OAEP on random data of short length.");
smg_comms_rsa_oaep 180 else
smg_comms_rsa_oaep 181 Put_Line("PASS: RSA_OAEP on random data of short length.");
smg_comms_rsa_oaep 182 end if;
smg_comms_rsa_oaep 183
smg_comms_rsa_oaep 184 end test_rsa_oaep;
smg_comms_rsa_oaep 185
smg_comms_rsa_oaep 186 -- helper methods
smg_comms_rsa_oaep 187
smg_comms_rsa_oaep 188 procedure PrintOctets( O: in Raw_Types.Octets; Title: in String ) is
smg_comms_rsa_oaep 189 begin
smg_comms_rsa_oaep 190 Put_Line(Title);
smg_comms_rsa_oaep 191 for V of O loop
smg_comms_rsa_oaep 192 Put(Unsigned_8'Image(V) & " ");
smg_comms_rsa_oaep 193 end loop;
smg_comms_rsa_oaep 194 New_Line;
smg_comms_rsa_oaep 195 end PrintOctets;
smg_comms_rsa_oaep 196
smg_comms_rsa_oaep 197 end Test_RSA_OAEP;