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_ch13_smg_rng 11 /* A way to determine endianness at runtime.
eucrypt_ch13_smg_rng 12 * Required for diddling a float's mantissa for instance.
eucrypt_ch13_smg_rng 13 */
eucrypt_ch13_smg_rng 14 static const int onect = 1;
eucrypt_ch13_smg_rng 15 #define is_bigendian() ( (*(char*)&onect) == 0 )
eucrypt_ch13_smg_rng 16
eucrypt_ch4_rpng 17 /*
eucrypt_ch4_rpng 18 * These are constants as per TMSR RSA specification, NOT knobs!
eucrypt_ch4_rpng 19 * TMSR key length is 4096 bits (512 octets); this means 2 primes of 2048 bits (256 octets) each.
eucrypt_ch4_rpng 20 * 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 21 */
eucrypt_ch4_rpng 22 static const int KEY_LENGTH_OCTETS = 512;
eucrypt_ch4_rpng 23
eucrypt_ch12_wrap... 24 /*
eucrypt_ch12_wrap... 25 * This is the maximum length of a plain-text message (in octets) that can be
eucrypt_ch12_wrap... 26 * oeap+rsa encrypted in a single block. Its value is defined in smg_oaep.ads
eucrypt_ch12_wrap... 27 */
eucrypt_ch12_wrap... 28 extern int max_len_msg;
eucrypt_ch12_wrap... 29
eucrypt_ch12_wrap... 30 /*
eucrypt_ch12_wrap... 31 * ada-exported oaep encrypt
eucrypt_ch12_wrap... 32 */
eucrypt_ch12_wrap... 33 extern void oaep_encrypt_c( char* msg, int msglen,
eucrypt_ch12_wrap... 34 char* entropy, int entlen,
eucrypt_ch12_wrap... 35 char* encr, int encrlen,
eucrypt_ch12_wrap... 36 int* success);
eucrypt_ch12_wrap... 37
eucrypt_ch12_wrap... 38 /*
eucrypt_ch12_wrap... 39 * ada-exported oaep decrypt
eucrypt_ch12_wrap... 40 */
eucrypt_ch12_wrap... 41 extern void oaep_decrypt_c( char* encr, int encrlen,
eucrypt_ch12_wrap... 42 char* decr, int* decrlen,
eucrypt_ch12_wrap... 43 int* success);
eucrypt_ch12_wrap... 44
eucrypt_ch5_rsa_keys 45 typedef struct {
eucrypt_ch5_rsa_keys 46 MPI n; /* modulus */
eucrypt_ch5_rsa_keys 47 MPI e; /* public exponent */
eucrypt_ch5_rsa_keys 48 } RSA_public_key;
eucrypt_ch5_rsa_keys 49
eucrypt_ch5_rsa_keys 50 typedef struct {
eucrypt_ch5_rsa_keys 51 MPI n; /* public modulus */
eucrypt_ch5_rsa_keys 52 MPI e; /* public exponent */
eucrypt_ch5_rsa_keys 53 MPI d; /* private exponent: e*d=1 mod phi */
eucrypt_ch5_rsa_keys 54 MPI p; /* prime p */
eucrypt_ch5_rsa_keys 55 MPI q; /* prime q */
eucrypt_ch5_rsa_keys 56 MPI u; /* inverse of p mod q */
eucrypt_ch5_rsa_keys 57 } RSA_secret_key;
eucrypt_ch5_rsa_keys 58
eucrypt_ch5_rsa_keys 59
ch2_truerandom 60 /*********truerandom.c*********/
ch2_truerandom 61
ch2_truerandom 62 /*
ch2_truerandom 63 * Opens and configures (as per FG requirements) the specified entropy source (e.g. "/dev/ttyUSB0")
ch2_truerandom 64 * @param source_name the name of the file to open (e.g. "/dev/ttyUSB0")
ch2_truerandom 65 * @return the descriptor of the open file when successful; negative value otherwise
ch2_truerandom 66 */
ch2_truerandom 67 int open_entropy_source(char* source_name);
ch2_truerandom 68
ch2_truerandom 69
ch2_truerandom 70 /*
ch2_truerandom 71 * Returns noctets random octets (i.e. 8*noctets bits in total) as obtained from EuCrypt's preferred source.
ch2_truerandom 72 * Preferred source is defined in knobs.h as ENTROPY_SOURCE and should be a TRNG (e.g. Fuckgoats).
ch2_truerandom 73 * @param nboctets the length of desired random sequence, in octets
ch2_truerandom 74 * @param out pointer to allocated memory space for the requested random noctets; NB: this method does NOT allocate space!
ch2_truerandom 75 * @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 76 */
ch2_truerandom 77 int get_random_octets(int noctets, unsigned char *out);
ch2_truerandom 78
ch2_truerandom 79 /* Returns noctets random octets as obtained from the specified "from" source;
ch2_truerandom 80 * NB: the "from" source is considered to be the handle of an already opened stream;
ch2_truerandom 81 * This method will simply attempt to read from the source as needed!
ch2_truerandom 82 *
ch2_truerandom 83 * @param noctets the length of desired random sequence, in octets
ch2_truerandom 84 * @param out pointer to allocated memory space for the requested random octets;
ch2_truerandom 85 * NB: this method does NOT allocate space!
ch2_truerandom 86 * @param from handle of an already opened entropy source - this method will just READ from it as needed
ch2_truerandom 87 * @return the actual number of octets that were obtained
ch2_truerandom 88 */
ch2_truerandom 89 int get_random_octets_from(int noctets, unsigned char *out, int from);
ch2_truerandom 90
eucrypt_ch13_smg_rng 91 /* Returns (in parameter *n) a *potentially biased* random float between 0 and 1
eucrypt_ch13_smg_rng 92 * Uses bits from ENTROPY_SOURCE but it rounds when converting to float
eucrypt_ch13_smg_rng 93 * NB: This function rounds impredictably.
eucrypt_ch13_smg_rng 94 Use it ONLY if LSB normalization is insignificant to you!
eucrypt_ch13_smg_rng 95 * This function uses rng_uint64 below.
eucrypt_ch13_smg_rng 96 *
eucrypt_ch13_smg_rng 97 * @param n - a float value (LSB rounded) between 0 and 1, obtained using
eucrypt_ch13_smg_rng 98 * a 64-bit random integer (64 bits from ENTROPY_SOURCE)
eucrypt_ch13_smg_rng 99 * @return - a positive value on success and a negative value in case of error
eucrypt_ch13_smg_rng 100 * main possible cause for error: failure to open ENTROPY_SOURCE.
eucrypt_ch13_smg_rng 101 * NB: a non-responsive/malconfigured source can result in blocking
eucrypt_ch13_smg_rng 102 */
eucrypt_ch13_smg_rng 103 int rng_dirty_float(float *n);
eucrypt_ch13_smg_rng 104
eucrypt_ch13_smg_rng 105
eucrypt_ch13_smg_rng 106 /* Returns (in parameter *n) a randomly generated float between 1 and 2 using:
eucrypt_ch13_smg_rng 107 * - the IEEE 754/1985 format for single float representation
eucrypt_ch13_smg_rng 108 * - ENTROPY_SOURCE to obtain bits that are *directly* used as mantissa
eucrypt_ch13_smg_rng 109 * NB: this value is between 1 and 2 due to the normalised format that includes
eucrypt_ch13_smg_rng 110 * an implicit 1 ( i.e. value is (-1)^sign * 2^(e-127) * (1.mantissa) )
eucrypt_ch13_smg_rng 111 *
eucrypt_ch13_smg_rng 112 * From IEEE 754/1985, a description of the single float format:
eucrypt_ch13_smg_rng 113 * msb means most significant bit
eucrypt_ch13_smg_rng 114 * lsb means least significant bit
eucrypt_ch13_smg_rng 115 * 1 8 23 ... widths
eucrypt_ch13_smg_rng 116 * +-+-------+-----------------------+
eucrypt_ch13_smg_rng 117 * |s| e | f |
eucrypt_ch13_smg_rng 118 * +-+-------+-----------------------+
eucrypt_ch13_smg_rng 119 * msb lsb msb lsb ... order
eucrypt_ch13_smg_rng 120
eucrypt_ch13_smg_rng 121 * A 32-bit single format number X is divided as shown in the figure above. The
eucrypt_ch13_smg_rng 122 * value v of X is inferred from its constituent fields thus:
eucrypt_ch13_smg_rng 123 * 1. If e = 255 and f != 0 , then v is NaN regardless of s
eucrypt_ch13_smg_rng 124 * 2. If e = 255 and f = 0 , then v = (-1)^s INFINITY
eucrypt_ch13_smg_rng 125 * 3. If 0 < e < 255 , then v = (-1)^s * 2^(e-127) * ( 1.f )
eucrypt_ch13_smg_rng 126 * 4. If e = 0 and f != 0 , then v = (-1)^s * 2^(-126) * ( 0.f ) (denormalized
eucrypt_ch13_smg_rng 127 * numbers)
eucrypt_ch13_smg_rng 128 * 5. If e = 0 and f = 0 , then v = ( -1 )^s * 0 (zero)
eucrypt_ch13_smg_rng 129 *
eucrypt_ch13_smg_rng 130 * @param n - the address of an IEEE 754/1985 float: its mantissa will be set to
eucrypt_ch13_smg_rng 131 * random bits obtained from ENTROPY_SOURCE; its sign will be set
eucrypt_ch13_smg_rng 132 * to 0; its exponent will be set to 127 (the bias value so
eucrypt_ch13_smg_rng 133 * that the actual exponent is 0).
eucrypt_ch13_smg_rng 134 * @return - a positive value on success and a negative value in case of error
eucrypt_ch13_smg_rng 135 * main possible cause for error: failure to open ENTROPY_SOURCE.
eucrypt_ch13_smg_rng 136 * NB: a non-responsive/malconfigured source can result in blocking
eucrypt_ch13_smg_rng 137 */
eucrypt_ch13_smg_rng 138 int rng_float_754_1985(float *n);
eucrypt_ch13_smg_rng 139
eucrypt_ch13_smg_rng 140 /* Returns (in parameter *n) a random unsigned integer value on 32 bits.
eucrypt_ch13_smg_rng 141 * Uses random bits from ENTROPY_SOURCE that are directly interpreted as int
eucrypt_ch13_smg_rng 142 *
eucrypt_ch13_smg_rng 143 * @param n - it will contain the random integer obtained by interpreting 32
eucrypt_ch13_smg_rng 144 * bits from ENTROPY_SOURCE as an unsigned int value on 32 bits.
eucrypt_ch13_smg_rng 145 * @return - a positive value on success and a negative value in case of error
eucrypt_ch13_smg_rng 146 */
eucrypt_ch13_smg_rng 147 int rng_uint32( uint32_t *n );
eucrypt_ch13_smg_rng 148
eucrypt_ch13_smg_rng 149 /* Returns (in parameter *n) a random unsigned integer value on 64 bits.
eucrypt_ch13_smg_rng 150 * Uses random bits from ENTROPY_SOURCE that are directly interpreted as int
eucrypt_ch13_smg_rng 151 *
eucrypt_ch13_smg_rng 152 * @param n - it will contain the random integer obtained by interpreting 64
eucrypt_ch13_smg_rng 153 * bits from ENTROPY_SOURCE as an unsigned int value on 64 bits.
eucrypt_ch13_smg_rng 154 * @return - a positive value on success and a negative value in case of error
eucrypt_ch13_smg_rng 155 */
eucrypt_ch13_smg_rng 156 int rng_uint64( uint64_t *n );
eucrypt_ch13_smg_rng 157
eucrypt_ch3_mille... 158 /*********primegen.c*********/
eucrypt_ch3_mille... 159
eucrypt_ch3_mille... 160 /*
eucrypt_ch3_mille... 161 * This is an implementation of the Miller-Rabin probabilistic primality test:
eucrypt_ch3_mille... 162 * checking the specified number of randomly-chosen candidate witnesses
eucrypt_ch3_mille... 163 * (i.e. with an outer bound of (1/4)^nwitnesses).
eucrypt_ch3_mille... 164 * NB: a 1 result from this test means that the given n is indeed composite (non-prime)
eucrypt_ch3_mille... 165 but a 0 result does not fully guarantee that n is prime!
eucrypt_ch3_mille... 166 If this doesn't make sense to you, read more on probabilistic primality tests.
eucrypt_ch3_mille... 167 * @param n the candidate prime number;
eucrypt_ch3_mille... 168 the function will investigate whether this number is composite or *likely* to be prime.
eucrypt_ch3_mille... 169 How likely? It depends on the number of witnesses checked, see next parameter.
eucrypt_ch3_mille... 170 * @param nwitnesses this is the number of randomly chosen candidate witnesses to the compositeness of n
eucrypt_ch3_mille... 171 that will be checked; the outer bound of the algorithm depends on this.
eucrypt_ch3_mille... 172 * @param entropy_source the source of entropy (ready to read from) that will be used
eucrypt_ch3_mille... 173 to choose candidate witnesses to the compositeness of n.
eucrypt_ch3_mille... 174 * @return 1 if at least one witness to the compositeness of n has been found
eucrypt_ch3_mille... 175 (i.e. n is certainly composite);
eucrypt_ch3_mille... 176 0 if no witness to the compositeness of n was found (i.e. it is likely that n is prime)
eucrypt_ch3_mille... 177 * NB: the probability that n is *not* prime although this function returned 0 is
eucrypt_ch3_mille... 178 less than (1/4)^nwitnesses, but it is NOT zero.
eucrypt_ch3_mille... 179 */
eucrypt_ch3_mille... 180 int is_composite( MPI n, int nwitnesses, int entropy_source);
eucrypt_ch3_mille... 181
eucrypt_ch4_rpng 182 /**
eucrypt_ch4_rpng 183 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
eucrypt_ch4_rpng 184 * 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 185 * a prime of 8*noctets long will have only (8*noctets-3) bits that are randomly chosen!
eucrypt_ch4_rpng 186 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
eucrypt_ch4_rpng 187 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch4_rpng 188 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch4_rpng 189 * Preconditions:
eucrypt_ch4_rpng 190 * noctets > 0 (at least one octet!)
eucrypt_ch4_rpng 191 * output has known allocated memory for at least nlimbs(noctets)
eucrypt_ch4_rpng 192 * successful access to the entropy source
eucrypt_ch4_rpng 193 * @param noctets the length of the desired prime number, in octets
eucrypt_ch4_rpng 194 * @param output an MPI with sufficient memory allocated for a number that is noctets long
eucrypt_ch4_rpng 195 */
eucrypt_ch4_rpng 196 void gen_random_prime( unsigned int noctets, MPI output);
eucrypt_ch4_rpng 197
eucrypt_ch5_rsa_keys 198 /*********rsa.c*********/
eucrypt_ch5_rsa_keys 199 /*
eucrypt_ch5_rsa_keys 200 * Generates a pair of public+private RSA keys using directly the entropy source
eucrypt_ch5_rsa_keys 201 * specified in eucrypt/smg_rsa/include/knobs.h
eucrypt_ch5_rsa_keys 202 *
eucrypt_ch5_rsa_keys 203 * ALL RSA keys are 4096 bits out of 2 2048 bits primes, as per TMSR spec.
eucrypt_ch5_rsa_keys 204 *
eucrypt_ch5_rsa_keys 205 * @param sk a fully-allocated structure to hold the generated keypair (secret
eucrypt_ch5_rsa_keys 206 key structure holds all the elements anyway, public key is a subset of this)
eucrypt_ch5_rsa_keys 207 *
eucrypt_ch5_rsa_keys 208 * NB: this procedure does NOT allocate memory for components in sk!
eucrypt_ch5_rsa_keys 209 * caller should ALLOCATE enough memory for all the MPIs in sk
eucrypt_ch5_rsa_keys 210 * Precondition:
eucrypt_ch5_rsa_keys 211 * MPIs in sk have known allocated memory for the nlimbs fitting their TMSR size
eucrypt_ch5_rsa_keys 212 */
eucrypt_ch5_rsa_keys 213 void gen_keypair( RSA_secret_key *sk );
eucrypt_ch5_rsa_keys 214
eucrypt_ch5_rsa_keys 215 /****************
eucrypt_ch5_rsa_keys 216 * Public key operation. Encrypt input with pk and store result into output.
eucrypt_ch5_rsa_keys 217 *
eucrypt_ch5_rsa_keys 218 * output = input^e mod n , where e,n are elements of pkey.
eucrypt_ch5_rsa_keys 219 * NB: caller should allocate *sufficient* memory for output to hold the result.
eucrypt_ch5_rsa_keys 220 * NB: NO checks are made on input!
eucrypt_ch5_rsa_keys 221 *
eucrypt_ch5_rsa_keys 222 * @param output MPI with enough allocated memory to hold result of encryption
eucrypt_ch5_rsa_keys 223 * @param input MPI containing content to encrypt; it *has to be* different from
eucrypt_ch5_rsa_keys 224 output!
eucrypt_ch5_rsa_keys 225 * @param pk the public key that will be used to encrypt input
eucrypt_ch5_rsa_keys 226 *
eucrypt_ch5_rsa_keys 227 * Precondition:
eucrypt_ch5_rsa_keys 228 * output != input
eucrypt_ch5_rsa_keys 229 * Output and input have to be two distinct MPIs because of the sorry state of
eucrypt_ch5_rsa_keys 230 the underlying mpi lib that can't handle properly the case when those are the
eucrypt_ch5_rsa_keys 231 same.
eucrypt_ch5_rsa_keys 232 */
eucrypt_ch5_rsa_keys 233 void public_rsa( MPI output, MPI input, RSA_public_key *pk );
eucrypt_ch5_rsa_keys 234
eucrypt_ch5_rsa_keys 235
eucrypt_ch5_rsa_keys 236 /****************
eucrypt_ch5_rsa_keys 237 * Secret key operation. Decrypt input with sk and store result in output.
eucrypt_ch5_rsa_keys 238 *
eucrypt_ch5_rsa_keys 239 * output = input^d mod n , where d, n are elements of skey.
eucrypt_ch5_rsa_keys 240 *
eucrypt_ch5_rsa_keys 241 * This implementation uses the Chinese Remainder Theorem (CRT):
eucrypt_ch5_rsa_keys 242 *
eucrypt_ch5_rsa_keys 243 * out1 = input ^ (d mod (p-1)) mod p
eucrypt_ch5_rsa_keys 244 * out2 = input ^ (d mod (q-1)) mod q
eucrypt_ch5_rsa_keys 245 * h = u * (out2 - out1) mod q
eucrypt_ch5_rsa_keys 246 * output = out1 + h * p
eucrypt_ch5_rsa_keys 247 *
eucrypt_ch5_rsa_keys 248 * where out1, out2 and h are intermediate values, d,n,p,q,u are elements of
eucrypt_ch5_rsa_keys 249 skey. By using CRT, encryption is *faster*. Decide for yourself if this fits
eucrypt_ch5_rsa_keys 250 your needs though!
eucrypt_ch5_rsa_keys 251 * NB: it is the caller's responsibility to allocate memory for output!
eucrypt_ch5_rsa_keys 252 * NB: NO checks are made on input!
eucrypt_ch5_rsa_keys 253 *
eucrypt_ch5_rsa_keys 254 * @param output MPI with enough allocated memory to hold result of decryption
eucrypt_ch5_rsa_keys 255 * @param input MPI containing content to decrypt
eucrypt_ch5_rsa_keys 256 * @param sk the secret key that will be used to decrypt input
eucrypt_ch5_rsa_keys 257 */
eucrypt_ch5_rsa_keys 258 void secret_rsa( MPI output, MPI input, RSA_secret_key *sk );
eucrypt_ch5_rsa_keys 259
eucrypt_ch12_wrap... 260 /*********
eucrypt_ch12_wrap... 261 * @param output - an MPI with KEY_LENGTH_OCTETS octets allocated space;
eucrypt_ch12_wrap... 262 it will hold the result: (rsa(oaep(input), pk))
eucrypt_ch12_wrap... 263 @param input - the plain-text message to be encrypted; maximum length is
eucrypt_ch12_wrap... 264 245 octets (1960 bits)
eucrypt_ch12_wrap... 265 @param pk - public key with which to encrypt
eucrypt_ch12_wrap... 266 NB: this method does NOT allocate memory for output!
eucrypt_ch12_wrap... 267 preconditions:
eucrypt_ch12_wrap... 268 - output IS different from input!
eucrypt_ch12_wrap... 269 - output has at least KEY_LENGTH_OCTETS octets allocated space
eucrypt_ch12_wrap... 270 - input is AT MOST max_len_msg octets long (ct defined in smg_oaep.ads)
eucrypt_ch12_wrap... 271 */
eucrypt_ch12_wrap... 272 void rsa_oaep_encrypt( MPI output, MPI input, RSA_public_key *pk);
eucrypt_ch12_wrap... 273
eucrypt_ch12_wrap... 274 /*
eucrypt_ch12_wrap... 275 * Opposite operation to rsa_oaep_encrypt.
eucrypt_ch12_wrap... 276 * Attempts oaep_decrypt(rsa_decrypt(input))
eucrypt_ch12_wrap... 277 * @param output - an MPI to hold the result; allocated >= max_len_msg octets
eucrypt_ch12_wrap... 278 * @param input - an MPI previously obtained with rsa_oaep_encrypt
eucrypt_ch12_wrap... 279 * @param sk - the secret key with which to decrypt
eucrypt_ch12_wrap... 280 * @param success - this will be set to -1 if there is an error
eucrypt_ch12_wrap... 281 *
eucrypt_ch12_wrap... 282 * preconditions:
eucrypt_ch12_wrap... 283 * - output IS different from input!
eucrypt_ch12_wrap... 284 * - output has at least KEY_LENGTH_OCTETS octets allocated space
eucrypt_ch12_wrap... 285 * - input is precisely KEY_LENGTH_OCTETS
eucrypt_ch12_wrap... 286 */
eucrypt_ch12_wrap... 287 void rsa_oaep_decrypt( MPI output, MPI input, RSA_secret_key *sk, int *success);
ch2_truerandom 288
ch2_truerandom 289 #endif /*SMG_RSA*/
ch2_truerandom 290