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_ch12_wrap... 18 /*
eucrypt_ch12_wrap... 19 * This is the maximum length of a plain-text message (in octets) that can be
eucrypt_ch12_wrap... 20 * oeap+rsa encrypted in a single block. Its value is defined in smg_oaep.ads
eucrypt_ch12_wrap... 21 */
eucrypt_ch12_wrap... 22 extern int max_len_msg;
eucrypt_ch12_wrap... 23
eucrypt_ch12_wrap... 24 /*
eucrypt_ch12_wrap... 25 * ada-exported oaep encrypt
eucrypt_ch12_wrap... 26 */
eucrypt_ch12_wrap... 27 extern void oaep_encrypt_c( char* msg, int msglen,
eucrypt_ch12_wrap... 28 char* entropy, int entlen,
eucrypt_ch12_wrap... 29 char* encr, int encrlen,
eucrypt_ch12_wrap... 30 int* success);
eucrypt_ch12_wrap... 31
eucrypt_ch12_wrap... 32 /*
eucrypt_ch12_wrap... 33 * ada-exported oaep decrypt
eucrypt_ch12_wrap... 34 */
eucrypt_ch12_wrap... 35 extern void oaep_decrypt_c( char* encr, int encrlen,
eucrypt_ch12_wrap... 36 char* decr, int* decrlen,
eucrypt_ch12_wrap... 37 int* success);
eucrypt_ch12_wrap... 38
eucrypt_ch5_rsa_keys 39 typedef struct {
eucrypt_ch5_rsa_keys 40 MPI n; /* modulus */
eucrypt_ch5_rsa_keys 41 MPI e; /* public exponent */
eucrypt_ch5_rsa_keys 42 } RSA_public_key;
eucrypt_ch5_rsa_keys 43
eucrypt_ch5_rsa_keys 44 typedef struct {
eucrypt_ch5_rsa_keys 45 MPI n; /* public modulus */
eucrypt_ch5_rsa_keys 46 MPI e; /* public exponent */
eucrypt_ch5_rsa_keys 47 MPI d; /* private exponent: e*d=1 mod phi */
eucrypt_ch5_rsa_keys 48 MPI p; /* prime p */
eucrypt_ch5_rsa_keys 49 MPI q; /* prime q */
eucrypt_ch5_rsa_keys 50 MPI u; /* inverse of p mod q */
eucrypt_ch5_rsa_keys 51 } RSA_secret_key;
eucrypt_ch5_rsa_keys 52
eucrypt_ch5_rsa_keys 53
ch2_truerandom 54 /*********truerandom.c*********/
ch2_truerandom 55
ch2_truerandom 56 /*
ch2_truerandom 57 * Opens and configures (as per FG requirements) the specified entropy source (e.g. "/dev/ttyUSB0")
ch2_truerandom 58 * @param source_name the name of the file to open (e.g. "/dev/ttyUSB0")
ch2_truerandom 59 * @return the descriptor of the open file when successful; negative value otherwise
ch2_truerandom 60 */
ch2_truerandom 61 int open_entropy_source(char* source_name);
ch2_truerandom 62
ch2_truerandom 63
ch2_truerandom 64 /*
ch2_truerandom 65 * Returns noctets random octets (i.e. 8*noctets bits in total) as obtained from EuCrypt's preferred source.
ch2_truerandom 66 * Preferred source is defined in knobs.h as ENTROPY_SOURCE and should be a TRNG (e.g. Fuckgoats).
ch2_truerandom 67 * @param nboctets the length of desired random sequence, in octets
ch2_truerandom 68 * @param out pointer to allocated memory space for the requested random noctets; NB: this method does NOT allocate space!
ch2_truerandom 69 * @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 70 */
ch2_truerandom 71 int get_random_octets(int noctets, unsigned char *out);
ch2_truerandom 72
ch2_truerandom 73 /* Returns noctets random octets as obtained from the specified "from" source;
ch2_truerandom 74 * NB: the "from" source is considered to be the handle of an already opened stream;
ch2_truerandom 75 * This method will simply attempt to read from the source as needed!
ch2_truerandom 76 *
ch2_truerandom 77 * @param noctets the length of desired random sequence, in octets
ch2_truerandom 78 * @param out pointer to allocated memory space for the requested random octets;
ch2_truerandom 79 * NB: this method does NOT allocate space!
ch2_truerandom 80 * @param from handle of an already opened entropy source - this method will just READ from it as needed
ch2_truerandom 81 * @return the actual number of octets that were obtained
ch2_truerandom 82 */
ch2_truerandom 83 int get_random_octets_from(int noctets, unsigned char *out, int from);
ch2_truerandom 84
eucrypt_ch3_mille... 85 /*********primegen.c*********/
eucrypt_ch3_mille... 86
eucrypt_ch3_mille... 87 /*
eucrypt_ch3_mille... 88 * This is an implementation of the Miller-Rabin probabilistic primality test:
eucrypt_ch3_mille... 89 * checking the specified number of randomly-chosen candidate witnesses
eucrypt_ch3_mille... 90 * (i.e. with an outer bound of (1/4)^nwitnesses).
eucrypt_ch3_mille... 91 * NB: a 1 result from this test means that the given n is indeed composite (non-prime)
eucrypt_ch3_mille... 92 but a 0 result does not fully guarantee that n is prime!
eucrypt_ch3_mille... 93 If this doesn't make sense to you, read more on probabilistic primality tests.
eucrypt_ch3_mille... 94 * @param n the candidate prime number;
eucrypt_ch3_mille... 95 the function will investigate whether this number is composite or *likely* to be prime.
eucrypt_ch3_mille... 96 How likely? It depends on the number of witnesses checked, see next parameter.
eucrypt_ch3_mille... 97 * @param nwitnesses this is the number of randomly chosen candidate witnesses to the compositeness of n
eucrypt_ch3_mille... 98 that will be checked; the outer bound of the algorithm depends on this.
eucrypt_ch3_mille... 99 * @param entropy_source the source of entropy (ready to read from) that will be used
eucrypt_ch3_mille... 100 to choose candidate witnesses to the compositeness of n.
eucrypt_ch3_mille... 101 * @return 1 if at least one witness to the compositeness of n has been found
eucrypt_ch3_mille... 102 (i.e. n is certainly composite);
eucrypt_ch3_mille... 103 0 if no witness to the compositeness of n was found (i.e. it is likely that n is prime)
eucrypt_ch3_mille... 104 * NB: the probability that n is *not* prime although this function returned 0 is
eucrypt_ch3_mille... 105 less than (1/4)^nwitnesses, but it is NOT zero.
eucrypt_ch3_mille... 106 */
eucrypt_ch3_mille... 107 int is_composite( MPI n, int nwitnesses, int entropy_source);
eucrypt_ch3_mille... 108
eucrypt_ch4_rpng 109 /**
eucrypt_ch4_rpng 110 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
eucrypt_ch4_rpng 111 * 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 112 * a prime of 8*noctets long will have only (8*noctets-3) bits that are randomly chosen!
eucrypt_ch4_rpng 113 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
eucrypt_ch4_rpng 114 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch4_rpng 115 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch4_rpng 116 * Preconditions:
eucrypt_ch4_rpng 117 * noctets > 0 (at least one octet!)
eucrypt_ch4_rpng 118 * output has known allocated memory for at least nlimbs(noctets)
eucrypt_ch4_rpng 119 * successful access to the entropy source
eucrypt_ch4_rpng 120 * @param noctets the length of the desired prime number, in octets
eucrypt_ch4_rpng 121 * @param output an MPI with sufficient memory allocated for a number that is noctets long
eucrypt_ch4_rpng 122 */
eucrypt_ch4_rpng 123 void gen_random_prime( unsigned int noctets, MPI output);
eucrypt_ch4_rpng 124
eucrypt_ch5_rsa_keys 125 /*********rsa.c*********/
eucrypt_ch5_rsa_keys 126 /*
eucrypt_ch5_rsa_keys 127 * Generates a pair of public+private RSA keys using directly the entropy source
eucrypt_ch5_rsa_keys 128 * specified in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch5_rsa_keys 129 *
eucrypt_ch5_rsa_keys 130 * ALL RSA keys are 4096 bits out of 2 2048 bits primes, as per TMSR spec.
eucrypt_ch5_rsa_keys 131 *
eucrypt_ch5_rsa_keys 132 * @param sk a fully-allocated structure to hold the generated keypair (secret
eucrypt_ch5_rsa_keys 133 key structure holds all the elements anyway, public key is a subset of this)
eucrypt_ch5_rsa_keys 134 *
eucrypt_ch5_rsa_keys 135 * NB: this procedure does NOT allocate memory for components in sk!
eucrypt_ch5_rsa_keys 136 * caller should ALLOCATE enough memory for all the MPIs in sk
eucrypt_ch5_rsa_keys 137 * Precondition:
eucrypt_ch5_rsa_keys 138 * MPIs in sk have known allocated memory for the nlimbs fitting their TMSR size
eucrypt_ch5_rsa_keys 139 */
eucrypt_ch5_rsa_keys 140 void gen_keypair( RSA_secret_key *sk );
eucrypt_ch5_rsa_keys 141
eucrypt_ch5_rsa_keys 142 /****************
eucrypt_ch5_rsa_keys 143 * Public key operation. Encrypt input with pk and store result into output.
eucrypt_ch5_rsa_keys 144 *
eucrypt_ch5_rsa_keys 145 * output = input^e mod n , where e,n are elements of pkey.
eucrypt_ch5_rsa_keys 146 * NB: caller should allocate *sufficient* memory for output to hold the result.
eucrypt_ch5_rsa_keys 147 * NB: NO checks are made on input!
eucrypt_ch5_rsa_keys 148 *
eucrypt_ch5_rsa_keys 149 * @param output MPI with enough allocated memory to hold result of encryption
eucrypt_ch5_rsa_keys 150 * @param input MPI containing content to encrypt; it *has to be* different from
eucrypt_ch5_rsa_keys 151 output!
eucrypt_ch5_rsa_keys 152 * @param pk the public key that will be used to encrypt input
eucrypt_ch5_rsa_keys 153 *
eucrypt_ch5_rsa_keys 154 * Precondition:
eucrypt_ch5_rsa_keys 155 * output != input
eucrypt_ch5_rsa_keys 156 * Output and input have to be two distinct MPIs because of the sorry state of
eucrypt_ch5_rsa_keys 157 the underlying mpi lib that can't handle properly the case when those are the
eucrypt_ch5_rsa_keys 158 same.
eucrypt_ch5_rsa_keys 159 */
eucrypt_ch5_rsa_keys 160 void public_rsa( MPI output, MPI input, RSA_public_key *pk );
eucrypt_ch5_rsa_keys 161
eucrypt_ch5_rsa_keys 162
eucrypt_ch5_rsa_keys 163 /****************
eucrypt_ch5_rsa_keys 164 * Secret key operation. Decrypt input with sk and store result in output.
eucrypt_ch5_rsa_keys 165 *
eucrypt_ch5_rsa_keys 166 * output = input^d mod n , where d, n are elements of skey.
eucrypt_ch5_rsa_keys 167 *
eucrypt_ch5_rsa_keys 168 * This implementation uses the Chinese Remainder Theorem (CRT):
eucrypt_ch5_rsa_keys 169 *
eucrypt_ch5_rsa_keys 170 * out1 = input ^ (d mod (p-1)) mod p
eucrypt_ch5_rsa_keys 171 * out2 = input ^ (d mod (q-1)) mod q
eucrypt_ch5_rsa_keys 172 * h = u * (out2 - out1) mod q
eucrypt_ch5_rsa_keys 173 * output = out1 + h * p
eucrypt_ch5_rsa_keys 174 *
eucrypt_ch5_rsa_keys 175 * where out1, out2 and h are intermediate values, d,n,p,q,u are elements of
eucrypt_ch5_rsa_keys 176 skey. By using CRT, encryption is *faster*. Decide for yourself if this fits
eucrypt_ch5_rsa_keys 177 your needs though!
eucrypt_ch5_rsa_keys 178 * NB: it is the caller's responsibility to allocate memory for output!
eucrypt_ch5_rsa_keys 179 * NB: NO checks are made on input!
eucrypt_ch5_rsa_keys 180 *
eucrypt_ch5_rsa_keys 181 * @param output MPI with enough allocated memory to hold result of decryption
eucrypt_ch5_rsa_keys 182 * @param input MPI containing content to decrypt
eucrypt_ch5_rsa_keys 183 * @param sk the secret key that will be used to decrypt input
eucrypt_ch5_rsa_keys 184 */
eucrypt_ch5_rsa_keys 185 void secret_rsa( MPI output, MPI input, RSA_secret_key *sk );
eucrypt_ch5_rsa_keys 186
eucrypt_ch12_wrap... 187 /*********
eucrypt_ch12_wrap... 188 * @param output - an MPI with KEY_LENGTH_OCTETS octets allocated space;
eucrypt_ch12_wrap... 189 it will hold the result: (rsa(oaep(input), pk))
eucrypt_ch12_wrap... 190 @param input - the plain-text message to be encrypted; maximum length is
eucrypt_ch12_wrap... 191 245 octets (1960 bits)
eucrypt_ch12_wrap... 192 @param pk - public key with which to encrypt
eucrypt_ch12_wrap... 193 NB: this method does NOT allocate memory for output!
eucrypt_ch12_wrap... 194 preconditions:
eucrypt_ch12_wrap... 195 - output IS different from input!
eucrypt_ch12_wrap... 196 - output has at least KEY_LENGTH_OCTETS octets allocated space
eucrypt_ch12_wrap... 197 - input is AT MOST max_len_msg octets long (ct defined in smg_oaep.ads)
eucrypt_ch12_wrap... 198 */
eucrypt_ch12_wrap... 199 void rsa_oaep_encrypt( MPI output, MPI input, RSA_public_key *pk);
eucrypt_ch12_wrap... 200
eucrypt_ch12_wrap... 201 /*
eucrypt_ch12_wrap... 202 * Opposite operation to rsa_oaep_encrypt.
eucrypt_ch12_wrap... 203 * Attempts oaep_decrypt(rsa_decrypt(input))
eucrypt_ch12_wrap... 204 * @param output - an MPI to hold the result; allocated >= max_len_msg octets
eucrypt_ch12_wrap... 205 * @param input - an MPI previously obtained with rsa_oaep_encrypt
eucrypt_ch12_wrap... 206 * @param sk - the secret key with which to decrypt
eucrypt_ch12_wrap... 207 * @param success - this will be set to -1 if there is an error
eucrypt_ch12_wrap... 208 *
eucrypt_ch12_wrap... 209 * preconditions:
eucrypt_ch12_wrap... 210 * - output IS different from input!
eucrypt_ch12_wrap... 211 * - output has at least KEY_LENGTH_OCTETS octets allocated space
eucrypt_ch12_wrap... 212 * - input is precisely KEY_LENGTH_OCTETS
eucrypt_ch12_wrap... 213 */
eucrypt_ch12_wrap... 214 void rsa_oaep_decrypt( MPI output, MPI input, RSA_secret_key *sk, int *success);
ch2_truerandom 215
ch2_truerandom 216 #endif /*SMG_RSA*/
ch2_truerandom 217