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