-
+ C4D51B3D41CA323C78B1C7A591B002A59FC756A1D895041DD2D3DDF4F2F2FCB60714C65E6A338949D8CE2AC5EF2BCCCB1365C97842E013849707CEFA4E633A4B
smg_comms/src/oaep.ads
(0 . 0)(1 . 87)
969 -- Implementation of TMSR's OAEP with Keccak as hash function
970 -- NB: this uses Eulora's protocol constants (esp. RSA key length) and types.
971 --
972 -- S.MG, 2018
973
974 with Keccak; -- Keccak is used as hash function
975 with Raw_Types; -- Eulora's protocol raw types and constant values
976
977 with Interfaces; use Interfaces; -- for Unsigned_8 type and bit-level ops
978
979 package OAEP is
980 pragma Pure( OAEP ); -- stateless, no side effects -> can cache calls
981
982 -- constants for OAEP
983 OAEP_LENGTH_OCTETS : constant := Raw_Types.RSA_KEY_OCTETS;
984 OAEP_LENGTH_BITS : constant := OAEP_LENGTH_OCTETS * 8;
985 OAEP_HALF_OCTETS : constant := OAEP_LENGTH_OCTETS / 2;
986 TMSR_STR : constant String := "TMSR-RSA";
987 -- "TMSR-RSA" as unsigned_8 values:
988 TMSR : constant Raw_Types.Octets := (84,77,83,82,45,82,83,65);
989 MAX_LEN_MSG : constant Natural := OAEP_HALF_OCTETS -
990 TMSR_STR'Length - 3;
991
992 -- subtypes for OAEP encrypt/decrypt
993 subtype OAEP_Block is Raw_Types.Octets( 1 .. OAEP_LENGTH_OCTETS );
994 subtype OAEP_HALF is Raw_Types.Octets( 1 .. OAEP_HALF_OCTETS );
995
996 -- padding & formatting of maximum MAX_LEN_MSG octets of the given input
997 -- uses TMSR's OAEP schema:
998 -- 1.format M00 as: [random octet][sz1][sz2]"TMSR-RSA"[random]*Message
999 -- where sz1 and sz2 store the length of the message in bits
1000 -- the random octets before message are padding to make OAEP_LENGTH_OCTETS
1001 -- 2. R = OAEP_HALF_OCTETS random bits
1002 -- 3. X = M00 xor hash(R)
1003 -- 4. Y = R xor hash(X)
1004 -- 5. Result is X || Y
1005 -- NB: the Entropy parameter should be random octets from which this method
1006 -- will use as many as required for the OAEP encryption of given Msg
1007 -- NB: at MOST MAX_LEN_MSG octets of Msg! (Msg at most MAX_LEN_MSG*8 bits!)
1008 procedure OAEP_Encrypt( Msg : in Raw_Types.Octets;
1009 Entropy : in OAEP_Block;
1010 Output : out OAEP_Block);
1011
1012
1013 -- This is the opposite of OAEP_Encrypt above.
1014 -- @param Encr - an OAEP block previously obtained from OAEP_Encrypt
1015 -- @param Len - this will hold the length of the obtained message (in bits!)
1016 -- @param Output - the first Len octets of this are the recovered message
1017 -- @param Success - set to TRUE if message was recovered, false otherwise
1018 -- NB: when Success is FALSE, both Len and Output have undefined values
1019 procedure OAEP_Decrypt( Encr : in OAEP_Block;
1020 Len : out Natural;
1021 Output : out OAEP_HALF;
1022 Success : out Boolean);
1023
1024 private
1025 -- gnat-specific methods for bit-level operations
1026 function Shift_Right( Value : Unsigned_8;
1027 Amount : Natural )
1028 return Unsigned_8;
1029 pragma Import(Intrinsic, Shift_Right);
1030
1031 function Shift_Left( Value : Unsigned_8;
1032 Amount : Natural )
1033 return Unsigned_8;
1034 pragma Import(Intrinsic, Shift_Left);
1035
1036 -- helper method: xor 2 half-oaep blocks
1037 function XOR_Octets(A : in OAEP_HALF;
1038 B : in OAEP_HALF)
1039 return OAEP_HALF;
1040
1041 -- conversions between bitstream and string
1042 -- NB: caller has to ensure correct size of output parameter! no checks here.
1043 procedure ToOctets ( B : in Keccak.Bitstream;
1044 O : out Raw_Types.Octets );
1045
1046 procedure ToBitstream( O : in Raw_Types.Octets;
1047 B : out Keccak.Bitstream );
1048
1049 -- wrapper for Sponge to use Octets for input/output
1050 procedure HashKeccak( Input : in Raw_Types.Octets;
1051 Output : out Raw_Types.Octets;
1052 Block_Len : in Keccak.Keccak_Rate :=
1053 Keccak.Default_Bitrate);
1054
1055 end OAEP;