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