raw
ch2_truerandom          1 /* smg_rsa.h
ch2_truerandom 2 * S.MG, 2017
ch2_truerandom 3 */
ch2_truerandom 4
ch2_truerandom 5 #ifndef SMG_RSA_H
ch2_truerandom 6 #define SMG_RSA_H
ch2_truerandom 7
ch2_truerandom 8 #include "mpi.h"
ch2_truerandom 9 #include "knobs.h"
ch2_truerandom 10
eucrypt_ch4_rpng 11 /*
eucrypt_ch4_rpng 12 * These are constants as per TMSR RSA specification, NOT knobs!
eucrypt_ch4_rpng 13 * TMSR key length is 4096 bits (512 octets); this means 2 primes of 2048 bits (256 octets) each.
eucrypt_ch4_rpng 14 * NB: if you choose here an odd key length in octets you might end up with a smaller actual key, read the code.
eucrypt_ch4_rpng 15 */
eucrypt_ch4_rpng 16 static const int KEY_LENGTH_OCTETS = 512;
eucrypt_ch4_rpng 17
eucrypt_ch5_rsa_keys 18 typedef struct {
eucrypt_ch5_rsa_keys 19 MPI n; /* modulus */
eucrypt_ch5_rsa_keys 20 MPI e; /* public exponent */
eucrypt_ch5_rsa_keys 21 } RSA_public_key;
eucrypt_ch5_rsa_keys 22
eucrypt_ch5_rsa_keys 23 typedef struct {
eucrypt_ch5_rsa_keys 24 MPI n; /* public modulus */
eucrypt_ch5_rsa_keys 25 MPI e; /* public exponent */
eucrypt_ch5_rsa_keys 26 MPI d; /* private exponent: e*d=1 mod phi */
eucrypt_ch5_rsa_keys 27 MPI p; /* prime p */
eucrypt_ch5_rsa_keys 28 MPI q; /* prime q */
eucrypt_ch5_rsa_keys 29 MPI u; /* inverse of p mod q */
eucrypt_ch5_rsa_keys 30 } RSA_secret_key;
eucrypt_ch5_rsa_keys 31
eucrypt_ch5_rsa_keys 32
ch2_truerandom 33 /*********truerandom.c*********/
ch2_truerandom 34
ch2_truerandom 35 /*
ch2_truerandom 36 * Opens and configures (as per FG requirements) the specified entropy source (e.g. "/dev/ttyUSB0")
ch2_truerandom 37 * @param source_name the name of the file to open (e.g. "/dev/ttyUSB0")
ch2_truerandom 38 * @return the descriptor of the open file when successful; negative value otherwise
ch2_truerandom 39 */
ch2_truerandom 40 int open_entropy_source(char* source_name);
ch2_truerandom 41
ch2_truerandom 42
ch2_truerandom 43 /*
ch2_truerandom 44 * Returns noctets random octets (i.e. 8*noctets bits in total) as obtained from EuCrypt's preferred source.
ch2_truerandom 45 * Preferred source is defined in knobs.h as ENTROPY_SOURCE and should be a TRNG (e.g. Fuckgoats).
ch2_truerandom 46 * @param nboctets the length of desired random sequence, in octets
ch2_truerandom 47 * @param out pointer to allocated memory space for the requested random noctets; NB: this method does NOT allocate space!
ch2_truerandom 48 * @return the actual number of octets that were obtained from the currently configured entropy source (this is equal to noctets on successful read of required noctets)
ch2_truerandom 49 */
ch2_truerandom 50 int get_random_octets(int noctets, unsigned char *out);
ch2_truerandom 51
ch2_truerandom 52 /* Returns noctets random octets as obtained from the specified "from" source;
ch2_truerandom 53 * NB: the "from" source is considered to be the handle of an already opened stream;
ch2_truerandom 54 * This method will simply attempt to read from the source as needed!
ch2_truerandom 55 *
ch2_truerandom 56 * @param noctets the length of desired random sequence, in octets
ch2_truerandom 57 * @param out pointer to allocated memory space for the requested random octets;
ch2_truerandom 58 * NB: this method does NOT allocate space!
ch2_truerandom 59 * @param from handle of an already opened entropy source - this method will just READ from it as needed
ch2_truerandom 60 * @return the actual number of octets that were obtained
ch2_truerandom 61 */
ch2_truerandom 62 int get_random_octets_from(int noctets, unsigned char *out, int from);
ch2_truerandom 63
eucrypt_ch3_mille... 64 /*********primegen.c*********/
eucrypt_ch3_mille... 65
eucrypt_ch3_mille... 66 /*
eucrypt_ch3_mille... 67 * This is an implementation of the Miller-Rabin probabilistic primality test:
eucrypt_ch3_mille... 68 * checking the specified number of randomly-chosen candidate witnesses
eucrypt_ch3_mille... 69 * (i.e. with an outer bound of (1/4)^nwitnesses).
eucrypt_ch3_mille... 70 * NB: a 1 result from this test means that the given n is indeed composite (non-prime)
eucrypt_ch3_mille... 71 but a 0 result does not fully guarantee that n is prime!
eucrypt_ch3_mille... 72 If this doesn't make sense to you, read more on probabilistic primality tests.
eucrypt_ch3_mille... 73 * @param n the candidate prime number;
eucrypt_ch3_mille... 74 the function will investigate whether this number is composite or *likely* to be prime.
eucrypt_ch3_mille... 75 How likely? It depends on the number of witnesses checked, see next parameter.
eucrypt_ch3_mille... 76 * @param nwitnesses this is the number of randomly chosen candidate witnesses to the compositeness of n
eucrypt_ch3_mille... 77 that will be checked; the outer bound of the algorithm depends on this.
eucrypt_ch3_mille... 78 * @param entropy_source the source of entropy (ready to read from) that will be used
eucrypt_ch3_mille... 79 to choose candidate witnesses to the compositeness of n.
eucrypt_ch3_mille... 80 * @return 1 if at least one witness to the compositeness of n has been found
eucrypt_ch3_mille... 81 (i.e. n is certainly composite);
eucrypt_ch3_mille... 82 0 if no witness to the compositeness of n was found (i.e. it is likely that n is prime)
eucrypt_ch3_mille... 83 * NB: the probability that n is *not* prime although this function returned 0 is
eucrypt_ch3_mille... 84 less than (1/4)^nwitnesses, but it is NOT zero.
eucrypt_ch3_mille... 85 */
eucrypt_ch3_mille... 86 int is_composite( MPI n, int nwitnesses, int entropy_source);
eucrypt_ch3_mille... 87
eucrypt_ch4_rpng 88 /**
eucrypt_ch4_rpng 89 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
eucrypt_ch4_rpng 90 * NB: top 2 bits and bottom bit are ALWAYS 1! (i.e. a mask 110....01 is applied to the random bits)
eucrypt_ch4_rpng 91 * a prime of 8*noctets long will have only (8*noctets-3) bits that are randomly chosen!
eucrypt_ch4_rpng 92 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
eucrypt_ch4_rpng 93 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch4_rpng 94 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch4_rpng 95 * Preconditions:
eucrypt_ch4_rpng 96 * noctets > 0 (at least one octet!)
eucrypt_ch4_rpng 97 * output has known allocated memory for at least nlimbs(noctets)
eucrypt_ch4_rpng 98 * successful access to the entropy source
eucrypt_ch4_rpng 99 * @param noctets the length of the desired prime number, in octets
eucrypt_ch4_rpng 100 * @param output an MPI with sufficient memory allocated for a number that is noctets long
eucrypt_ch4_rpng 101 */
eucrypt_ch4_rpng 102 void gen_random_prime( unsigned int noctets, MPI output);
eucrypt_ch4_rpng 103
eucrypt_ch5_rsa_keys 104 /*********rsa.c*********/
eucrypt_ch5_rsa_keys 105 /*
eucrypt_ch5_rsa_keys 106 * Generates a pair of public+private RSA keys using directly the entropy source
eucrypt_ch5_rsa_keys 107 * specified in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch5_rsa_keys 108 *
eucrypt_ch5_rsa_keys 109 * ALL RSA keys are 4096 bits out of 2 2048 bits primes, as per TMSR spec.
eucrypt_ch5_rsa_keys 110 *
eucrypt_ch5_rsa_keys 111 * @param sk a fully-allocated structure to hold the generated keypair (secret
eucrypt_ch5_rsa_keys 112 key structure holds all the elements anyway, public key is a subset of this)
eucrypt_ch5_rsa_keys 113 *
eucrypt_ch5_rsa_keys 114 * NB: this procedure does NOT allocate memory for components in sk!
eucrypt_ch5_rsa_keys 115 * caller should ALLOCATE enough memory for all the MPIs in sk
eucrypt_ch5_rsa_keys 116 * Precondition:
eucrypt_ch5_rsa_keys 117 * MPIs in sk have known allocated memory for the nlimbs fitting their TMSR size
eucrypt_ch5_rsa_keys 118 */
eucrypt_ch5_rsa_keys 119 void gen_keypair( RSA_secret_key *sk );
eucrypt_ch5_rsa_keys 120
eucrypt_ch5_rsa_keys 121 /****************
eucrypt_ch5_rsa_keys 122 * Public key operation. Encrypt input with pk and store result into output.
eucrypt_ch5_rsa_keys 123 *
eucrypt_ch5_rsa_keys 124 * output = input^e mod n , where e,n are elements of pkey.
eucrypt_ch5_rsa_keys 125 * NB: caller should allocate *sufficient* memory for output to hold the result.
eucrypt_ch5_rsa_keys 126 * NB: NO checks are made on input!
eucrypt_ch5_rsa_keys 127 *
eucrypt_ch5_rsa_keys 128 * @param output MPI with enough allocated memory to hold result of encryption
eucrypt_ch5_rsa_keys 129 * @param input MPI containing content to encrypt; it *has to be* different from
eucrypt_ch5_rsa_keys 130 output!
eucrypt_ch5_rsa_keys 131 * @param pk the public key that will be used to encrypt input
eucrypt_ch5_rsa_keys 132 *
eucrypt_ch5_rsa_keys 133 * Precondition:
eucrypt_ch5_rsa_keys 134 * output != input
eucrypt_ch5_rsa_keys 135 * Output and input have to be two distinct MPIs because of the sorry state of
eucrypt_ch5_rsa_keys 136 the underlying mpi lib that can't handle properly the case when those are the
eucrypt_ch5_rsa_keys 137 same.
eucrypt_ch5_rsa_keys 138 */
eucrypt_ch5_rsa_keys 139 void public_rsa( MPI output, MPI input, RSA_public_key *pk );
eucrypt_ch5_rsa_keys 140
eucrypt_ch5_rsa_keys 141
eucrypt_ch5_rsa_keys 142 /****************
eucrypt_ch5_rsa_keys 143 * Secret key operation. Decrypt input with sk and store result in output.
eucrypt_ch5_rsa_keys 144 *
eucrypt_ch5_rsa_keys 145 * output = input^d mod n , where d, n are elements of skey.
eucrypt_ch5_rsa_keys 146 *
eucrypt_ch5_rsa_keys 147 * This implementation uses the Chinese Remainder Theorem (CRT):
eucrypt_ch5_rsa_keys 148 *
eucrypt_ch5_rsa_keys 149 * out1 = input ^ (d mod (p-1)) mod p
eucrypt_ch5_rsa_keys 150 * out2 = input ^ (d mod (q-1)) mod q
eucrypt_ch5_rsa_keys 151 * h = u * (out2 - out1) mod q
eucrypt_ch5_rsa_keys 152 * output = out1 + h * p
eucrypt_ch5_rsa_keys 153 *
eucrypt_ch5_rsa_keys 154 * where out1, out2 and h are intermediate values, d,n,p,q,u are elements of
eucrypt_ch5_rsa_keys 155 skey. By using CRT, encryption is *faster*. Decide for yourself if this fits
eucrypt_ch5_rsa_keys 156 your needs though!
eucrypt_ch5_rsa_keys 157 * NB: it is the caller's responsibility to allocate memory for output!
eucrypt_ch5_rsa_keys 158 * NB: NO checks are made on input!
eucrypt_ch5_rsa_keys 159 *
eucrypt_ch5_rsa_keys 160 * @param output MPI with enough allocated memory to hold result of decryption
eucrypt_ch5_rsa_keys 161 * @param input MPI containing content to decrypt
eucrypt_ch5_rsa_keys 162 * @param sk the secret key that will be used to decrypt input
eucrypt_ch5_rsa_keys 163 */
eucrypt_ch5_rsa_keys 164 void secret_rsa( MPI output, MPI input, RSA_secret_key *sk );
eucrypt_ch5_rsa_keys 165
ch2_truerandom 166
ch2_truerandom 167 #endif /*SMG_RSA*/
ch2_truerandom 168