-
+ 30C0E084AC56702B73EBF5609107A8B21B71B269F34B37D9067A542A94DC0D26526480FE52EFDA976752B292BE361CE4A4C7C1D3F2FAD8CC100FC06CE6C78BF7
smg_comms/src/rsa_oaep.ads
(0 . 0)(1 . 129)
1320 -- Ada implementation of RSA with OAEP according to TMSR and Eulora spec
1321 -- Uses:
1322 -- - Eulora's raw types (Ada, raw_types.ads)
1323 -- - Keccak hashes (Ada, keccak.ads/adb)
1324 -- - OAEP schema (Ada, oaep.ads/adb)
1325 -- - RNG (Ada, rng.ads/adb) for true random padding
1326 -- - C wrappers lib (C, c_wrappers/) for:
1327 -- - MPI (C, mpi/)
1328 -- - RSA (C, rsa/rsa.c)
1329 --
1330 -- S.MG, 2018
1331
1332 with Raw_Types;
1333 with Interfaces.C; use Interfaces.C;
1334
1335 package RSA_OAEP is
1336 -- exception for mismatched lengths when converting octets <-> char arrays
1337 Mismatched_Lengths_Error: exception;
1338
1339 -- public RSA key with n,e stored as raw octets
1340 type RSA_pkey is
1341 record
1342 n : Raw_Types.RSA_len; --public modulus
1343 e : Raw_Types.RSA_half; --public exponent
1344 end record; --RSA_pkey
1345
1346 -- private (secret) RSA key with components stored as raw octets
1347 type RSA_skey is
1348 record
1349 n : Raw_Types.RSA_len; --public modulus
1350 e : Raw_Types.RSA_half; --public exponent
1351 d : Raw_Types.RSA_len; --secret exponent e*d=1 mod phi; phi=(p-1)*(q-1)
1352 p : Raw_Types.RSA_half; --prime p
1353 q : Raw_Types.RSA_half; --prime q
1354 u : Raw_Types.RSA_half; --inverse of p mod q; for faster calculations
1355 end record; --RSA_skey
1356
1357 -- Encryption RSA+OAEP (i.e. using public key)
1358 -- NB: at most OAEP.MAX_LEN_MSG octets from Plain will be encrypted!
1359 -- Relies directly on:
1360 -- oaep.adb/ads
1361 -- c_wrappers.c ( RSA )
1362 -- rng.adb/ads ( random padding )
1363 procedure Encrypt( Plain: in Raw_Types.Octets;
1364 Key : in RSA_pkey;
1365 Encr : out Raw_Types.RSA_len );
1366
1367 -- Decryption RSA+OAEP (i.e. using private/secret key)
1368 -- The opposite of Encrypt above.
1369 -- NB: Plain has to have ENOUGH space for result!
1370 -- Result can be at most OAEP.MAX_LEN_MSG octets.
1371 -- Relies directly on:
1372 -- oaep.adb/ads
1373 -- c_wrappers.c (RSA)
1374 -- Plain_Len gives the length in OCTETS of the decrypted message.
1375 procedure Decrypt( Encr : in Raw_Types.RSA_len;
1376 Key : in RSA_skey;
1377 Plain : out Raw_Types.Octets;
1378 Plain_Len : out Natural;
1379 Success : out Boolean);
1380
1381 --helper methods:
1382 -- mainly conversions to/from C's char* and imports from C_wrappers
1383 -- encrypt with public RSA key given as struct, Ada style
1384 -- NB: result is potentially 0-led (i.e. at end of Encr not at start!)
1385 procedure Public_RSA( Plain: in Raw_Types.Octets;
1386 Key : in RSA_pkey;
1387 Encr : out Raw_Types.RSA_len);
1388
1389 -- encrypt with public RSA key given as char arrays, via C_Wrappers
1390 -- this returns the length of result because C functions trim leading 0s!
1391 function Public_RSA_C( Encr : out Interfaces.C.char_array;
1392 Encr_Len : in Integer;
1393 Plain : in Interfaces.C.char_array;
1394 Plain_Len : in Integer;
1395 RSA_N : in Interfaces.C.char_array;
1396 N_Len : in Integer;
1397 RSA_E : in Interfaces.C.char_array;
1398 E_Len : in Integer)
1399 return Integer;
1400 pragma Import(C, Public_RSA_C, "public_rsa_octets");
1401
1402 -- decrypt with private RSA key given as struct, Ada style
1403 -- NB: Plain has to have ENOUGH space!
1404 -- NB: Result is potentially 0-led (i.e. at the end of Plain, not at start!)
1405 -- @return actual length of result
1406 procedure Private_RSA( Encr : in Raw_Types.RSA_len;
1407 Key : in RSA_skey;
1408 Plain : out Raw_Types.Octets);
1409
1410 -- encrypt with private/secret RSA key given as char arrays (via C_wrappers)
1411 -- this returns length because C methods trim leading 0s
1412 function Private_RSA_C( Plain : out Interfaces.C.char_array;
1413 Plain_Len : in Integer;
1414 Encr : in Interfaces.C.char_array;
1415 Encr_Len : in Integer;
1416 RSA_N : in Interfaces.C.char_array;
1417 N_Len : in Integer;
1418 RSA_E : in Interfaces.C.char_array;
1419 E_Len : in Integer;
1420 RSA_D : in Interfaces.C.char_array;
1421 D_Len : in Integer;
1422 RSA_P : in Interfaces.C.char_array;
1423 P_Len : in Integer;
1424 RSA_Q : in Interfaces.C.char_array;
1425 Q_Len : in Integer;
1426 RSA_U : in Interfaces.C.char_array;
1427 U_Len : in Integer)
1428 return Integer;
1429 pragma Import( C, Private_RSA_C, "private_rsa_octets" );
1430
1431 -- convert from Ada's Octets (array of octets) to C's char* (char_array)
1432
1433 -- This copies the octets from O to the beginning of A
1434 -- NB: there are NO checks or memory allocations here!
1435 -- Caller has to make sure that:
1436 -- A has allocated space for at least O'Length octets!
1437 procedure Octets_To_Char_Array( O : in Raw_Types.Octets;
1438 A : out Interfaces.C.char_array);
1439
1440
1441 -- This copies first O'Length characters from A to O
1442 -- NB: this does NOT allocate /check memory!
1443 -- Caller has to ensure that:
1444 -- A has space at least O'Length characters
1445 procedure Char_Array_To_Octets( A : in Interfaces.C.char_array;
1446 O : out Raw_Types.Octets);
1447
1448 end RSA_OAEP;