raw
smg_comms_rsa_oaep      1 -- Implementation of TMSR's OAEP with Keccak as hash function
smg_comms_rsa_oaep 2 -- NB: this uses Eulora's protocol constants (esp. RSA key length) and types.
smg_comms_rsa_oaep 3 --
smg_comms_rsa_oaep 4 -- S.MG, 2018
smg_comms_rsa_oaep 5
smg_comms_rsa_oaep 6 with Keccak; -- Keccak is used as hash function
smg_comms_rsa_oaep 7 with Raw_Types; -- Eulora's protocol raw types and constant values
smg_comms_rsa_oaep 8
smg_comms_rsa_oaep 9 with Interfaces; use Interfaces; -- for Unsigned_8 type and bit-level ops
smg_comms_rsa_oaep 10
smg_comms_rsa_oaep 11 package OAEP is
smg_comms_rsa_oaep 12 pragma Pure( OAEP ); -- stateless, no side effects -> can cache calls
smg_comms_rsa_oaep 13
smg_comms_rsa_oaep 14 -- constants for OAEP
smg_comms_rsa_oaep 15 OAEP_LENGTH_OCTETS : constant := Raw_Types.RSA_KEY_OCTETS;
smg_comms_rsa_oaep 16 OAEP_LENGTH_BITS : constant := OAEP_LENGTH_OCTETS * 8;
smg_comms_rsa_oaep 17 OAEP_HALF_OCTETS : constant := OAEP_LENGTH_OCTETS / 2;
smg_comms_rsa_oaep 18 TMSR_STR : constant String := "TMSR-RSA";
smg_comms_rsa_oaep 19 -- "TMSR-RSA" as unsigned_8 values:
smg_comms_rsa_oaep 20 TMSR : constant Raw_Types.Octets := (84,77,83,82,45,82,83,65);
smg_comms_rsa_oaep 21 MAX_LEN_MSG : constant Natural := OAEP_HALF_OCTETS -
smg_comms_rsa_oaep 22 TMSR_STR'Length - 3;
smg_comms_rsa_oaep 23
smg_comms_rsa_oaep 24 -- subtypes for OAEP encrypt/decrypt
smg_comms_rsa_oaep 25 subtype OAEP_Block is Raw_Types.Octets( 1 .. OAEP_LENGTH_OCTETS );
smg_comms_rsa_oaep 26 subtype OAEP_HALF is Raw_Types.Octets( 1 .. OAEP_HALF_OCTETS );
smg_comms_rsa_oaep 27
smg_comms_rsa_oaep 28 -- padding & formatting of maximum MAX_LEN_MSG octets of the given input
smg_comms_rsa_oaep 29 -- uses TMSR's OAEP schema:
smg_comms_rsa_oaep 30 -- 1.format M00 as: [random octet][sz1][sz2]"TMSR-RSA"[random]*Message
smg_comms_rsa_oaep 31 -- where sz1 and sz2 store the length of the message in bits
smg_comms_rsa_oaep 32 -- the random octets before message are padding to make OAEP_LENGTH_OCTETS
smg_comms_rsa_oaep 33 -- 2. R = OAEP_HALF_OCTETS random bits
smg_comms_rsa_oaep 34 -- 3. X = M00 xor hash(R)
smg_comms_rsa_oaep 35 -- 4. Y = R xor hash(X)
smg_comms_rsa_oaep 36 -- 5. Result is X || Y
smg_comms_rsa_oaep 37 -- NB: the Entropy parameter should be random octets from which this method
smg_comms_rsa_oaep 38 -- will use as many as required for the OAEP encryption of given Msg
smg_comms_rsa_oaep 39 -- NB: at MOST MAX_LEN_MSG octets of Msg! (Msg at most MAX_LEN_MSG*8 bits!)
smg_comms_rsa_oaep 40 procedure OAEP_Encrypt( Msg : in Raw_Types.Octets;
smg_comms_rsa_oaep 41 Entropy : in OAEP_Block;
smg_comms_rsa_oaep 42 Output : out OAEP_Block);
smg_comms_rsa_oaep 43
smg_comms_rsa_oaep 44
smg_comms_rsa_oaep 45 -- This is the opposite of OAEP_Encrypt above.
smg_comms_rsa_oaep 46 -- @param Encr - an OAEP block previously obtained from OAEP_Encrypt
smg_comms_rsa_oaep 47 -- @param Len - this will hold the length of the obtained message (in bits!)
smg_comms_rsa_oaep 48 -- @param Output - the first Len octets of this are the recovered message
smg_comms_rsa_oaep 49 -- @param Success - set to TRUE if message was recovered, false otherwise
smg_comms_rsa_oaep 50 -- NB: when Success is FALSE, both Len and Output have undefined values
smg_comms_rsa_oaep 51 procedure OAEP_Decrypt( Encr : in OAEP_Block;
smg_comms_rsa_oaep 52 Len : out Natural;
smg_comms_rsa_oaep 53 Output : out OAEP_HALF;
smg_comms_rsa_oaep 54 Success : out Boolean);
smg_comms_rsa_oaep 55
smg_comms_rsa_oaep 56 private
smg_comms_rsa_oaep 57 -- gnat-specific methods for bit-level operations
smg_comms_rsa_oaep 58 function Shift_Right( Value : Unsigned_8;
smg_comms_rsa_oaep 59 Amount : Natural )
smg_comms_rsa_oaep 60 return Unsigned_8;
smg_comms_rsa_oaep 61 pragma Import(Intrinsic, Shift_Right);
smg_comms_rsa_oaep 62
smg_comms_rsa_oaep 63 function Shift_Left( Value : Unsigned_8;
smg_comms_rsa_oaep 64 Amount : Natural )
smg_comms_rsa_oaep 65 return Unsigned_8;
smg_comms_rsa_oaep 66 pragma Import(Intrinsic, Shift_Left);
smg_comms_rsa_oaep 67
smg_comms_rsa_oaep 68 -- helper method: xor 2 half-oaep blocks
smg_comms_rsa_oaep 69 function XOR_Octets(A : in OAEP_HALF;
smg_comms_rsa_oaep 70 B : in OAEP_HALF)
smg_comms_rsa_oaep 71 return OAEP_HALF;
smg_comms_rsa_oaep 72
smg_comms_rsa_oaep 73 -- conversions between bitstream and string
smg_comms_rsa_oaep 74 -- NB: caller has to ensure correct size of output parameter! no checks here.
smg_comms_rsa_oaep 75 procedure ToOctets ( B : in Keccak.Bitstream;
smg_comms_rsa_oaep 76 O : out Raw_Types.Octets );
smg_comms_rsa_oaep 77
smg_comms_rsa_oaep 78 procedure ToBitstream( O : in Raw_Types.Octets;
smg_comms_rsa_oaep 79 B : out Keccak.Bitstream );
smg_comms_rsa_oaep 80
smg_comms_rsa_oaep 81 -- wrapper for Sponge to use Octets for input/output
smg_comms_rsa_oaep 82 procedure HashKeccak( Input : in Raw_Types.Octets;
smg_comms_rsa_oaep 83 Output : out Raw_Types.Octets;
smg_comms_rsa_oaep 84 Block_Len : in Keccak.Keccak_Rate :=
smg_comms_rsa_oaep 85 Keccak.Default_Bitrate);
smg_comms_rsa_oaep 86
smg_comms_rsa_oaep 87 end OAEP;