150276Speter/* 2184989Srafan * Licensed Materials - Property of IBM 350276Speter * 450276Speter * trousers - An open source TCG Software Stack 550276Speter * 650276Speter * (C) Copyright International Business Machines Corp. 2006 750276Speter * 850276Speter */ 950276Speter 1050276Speter#include <stdlib.h> 1150276Speter#include <stdio.h> 1250276Speter#include <string.h> 1350276Speter#include <errno.h> 1450276Speter 1550276Speter#include "bi.h" 1650276Speter#include "list.h" 1750276Speter#include "daa_structs.h" 1850276Speter#include "daa_parameter.h" 1950276Speter#include "issuer.h" 2050276Speter 2150276Speterstatic const int ELEMENT = 0; 2250276Speterstatic const int EXPONENT = 1; 2350276Speter 2450276Speterextern void prime_init(); 2550276Speterextern void compute_safe_prime(bi_ptr result, int bit_length, int prime_certainty); 2650276Speter 2750276Speterbi_ptr 2850276Spetercompute_random_number_star( bi_ptr result, const bi_ptr element) 2950276Speter{ 30166124Srafan bi_t bi_tmp; 3150276Speter 3250276Speter bi_new(bi_tmp); 3350276Speter do { 3450276Speter compute_random_number(result, element); 35184989Srafan } while (!bi_equals_si(bi_gcd(bi_tmp, result, element), 1)); 3650276Speter 3750276Speter bi_free(bi_tmp); 38166124Srafan 39166124Srafan return result; 40166124Srafan} 41166124Srafan 42166124Srafan/* Compute a generator of the group of quadratic residue modulo n. The 43166124Srafan * generator will not be part of the subgroup of size 2. 44166124Srafan * n: modulus */ 45166124Srafanvoid 46166124Srafancompute_generator_quadratic_residue(bi_t qr, bi_t n) 47166124Srafan{ 48166124Srafan bi_t bi_tmp, bi_tmp1; 49166124Srafan 50166124Srafan bi_new(bi_tmp); 51166124Srafan bi_new(bi_tmp1); 52166124Srafan 53166124Srafan do { 54166124Srafan compute_random_number(qr, n); 55166124Srafan // qr = (qr ^ bi_2) % n 56166124Srafan bi_mod_exp(qr, qr, bi_2, n); 57166124Srafan } while (bi_cmp_si(qr, 1) == 0 || 58166124Srafan bi_cmp_si(bi_gcd(bi_tmp, n, bi_sub_si(bi_tmp1, qr, 1)), 1) != 0); 59166124Srafan 60166124Srafan bi_free(bi_tmp); 61166124Srafan bi_free(bi_tmp1); 6250276Speter} 6350276Speter 6476726Spetervoid 6550276Spetercompute_group_element(bi_ptr result[], 6650276Speter bi_ptr generator, 6750276Speter bi_ptr product_PQprime, 6850276Speter bi_ptr n) 6950276Speter{ 7050276Speter bi_t bi_tmp; 7150276Speter 7250276Speter bi_new(bi_tmp); 7350276Speter compute_random_number(bi_tmp, product_PQprime); 7450276Speter 7550276Speter // bi_tmp++ 7650276Speter bi_inc(bi_tmp); 7750276Speter 78166124Srafan // result[ELEMENT] := (generator ^ bi_tmp) mod n 79166124Srafan bi_mod_exp(result[ELEMENT], generator, bi_tmp, n); 8050276Speter bi_set(result[EXPONENT], bi_tmp); 8150276Speter bi_free(bi_tmp); 82166124Srafan} 8350276Speter 8450276Speter 8550276SpeterTSS_RESULT 86166124Srafangenerate_key_pair(UINT32 num_attributes_issuer, 8750276Speter UINT32 num_attributes_receiver, 8850276Speter UINT32 base_nameLength, 8950276Speter BYTE* base_name, 9050276Speter KEY_PAIR_WITH_PROOF_internal** key_pair_with_proof) 9150276Speter{ 92166124Srafan TSS_RESULT result = TSS_SUCCESS; 93166124Srafan int length_mod = DAA_PARAM_SIZE_RSA_MODULUS; 94166124Srafan int length; 9550276Speter int i; 9650276Speter TSS_DAA_PK_internal *public_key = NULL; 97166124Srafan BYTE *buffer = NULL; 98166124Srafan bi_ptr pPrime = NULL; 9950276Speter bi_ptr qPrime = NULL; 10050276Speter bi_ptr n = NULL; 10150276Speter bi_ptr p = NULL; 10250276Speter bi_ptr q = NULL; 103166124Srafan bi_ptr capital_s = NULL; 104166124Srafan bi_ptr capital_z = NULL; 105166124Srafan bi_ptr product_PQprime = NULL; 10650276Speter bi_ptr pair[2] = {NULL, NULL}; 10750276Speter bi_ptr xz = NULL; 108166124Srafan bi_ptr capital_r0 = NULL; 10950276Speter bi_ptr x0 = NULL; 11050276Speter bi_ptr capital_r1 = NULL; 111166124Srafan bi_ptr x1 = NULL; 11250276Speter bi_array_ptr x = NULL; 11350276Speter bi_array_ptr capital_r = NULL; 11450276Speter bi_array_ptr capitalRReceiver = NULL; 11550276Speter bi_array_ptr capitalRIssuer = NULL; 11650276Speter bi_ptr gamma = NULL; 11750276Speter bi_ptr capital_gamma = NULL; 11850276Speter bi_ptr rho = NULL; 11950276Speter bi_ptr r = NULL; 12050276Speter bi_ptr rho_double = NULL; 12150276Speter bi_t bi_tmp, bi_tmp1, bi_tmp2; 122166124Srafan 123166124Srafan bi_new(bi_tmp); 12450276Speter bi_new(bi_tmp1); 12550276Speter bi_new(bi_tmp2); 12650276Speter *key_pair_with_proof = NULL; 12750276Speter 12850276Speter // STEP 1 129166124Srafan LogDebug("Step 1 of 8 - compute modulus n (please wait: long process)\n"); 13050276Speter 131166124Srafan // FUTURE USAGE if( IS_DEBUG==0) 13250276Speter prime_init(); 13350276Speter p = bi_new_ptr(); 134166124Srafan q = bi_new_ptr(); 13550276Speter n = bi_new_ptr(); 13650276Speter 13750276Speter do { 138166124Srafan // FUTURE USAGE 13950276Speter /* compute_safe_prime( p, length_mod / 2); 140166124Srafan do { 141166124Srafan compute_safe_prime( q, 14250276Speter length_mod - (length_mod >> 1)); 14350276Speter } while( bi_cmp( p, q) ==0); 14450276Speter } else */ 14550276Speter { 14650276Speter bi_generate_safe_prime(p, length_mod / 2); 14750276Speter bi_generate_safe_prime(q, length_mod - (length_mod / 2)); 14850276Speter LogDebug("."); 14950276Speter } 15050276Speter // n = p*q 15150276Speter bi_mul(n, p, q); 15250276Speter } while(bi_length(n) != length_mod); 15350276Speter 15450276Speter pPrime = bi_new_ptr(); 155166124Srafan bi_sub(pPrime, p, bi_1); 156166124Srafan 15750276Speter // pPrime = (p - 1) >> 1 15850276Speter bi_shift_right(pPrime, pPrime, 1); 15950276Speter qPrime = bi_new_ptr(); 16050276Speter bi_sub(qPrime, q, bi_1); 16150276Speter 162166124Srafan // qPrime = (q - 1) >> 1 163166124Srafan bi_shift_right( qPrime, qPrime, 1); 164166124Srafan if (bi_is_probable_prime(pPrime) == 0) { 16550276Speter LogError("!! pPrime not a prime number: %s", bi_2_hex_char(pPrime)); 16650276Speter result = TSPERR(TSS_E_INTERNAL_ERROR); 167166124Srafan goto close; 16850276Speter } 169166124Srafan if (bi_is_probable_prime(qPrime) == 0) { 17050276Speter LogError("!! qPrime not a prime number: %s", bi_2_hex_char(qPrime)); 17150276Speter result = TSPERR(TSS_E_INTERNAL_ERROR); 17250276Speter goto close; 173166124Srafan } 17450276Speter LogDebug("p=%s", bi_2_hex_char(p)); 17550276Speter LogDebug("q=%s", bi_2_hex_char(q)); 176166124Srafan LogDebug("n=%s", bi_2_hex_char(n)); 17750276Speter 178166124Srafan // STEP 2 17950276Speter LogDebug("Step 2 - choose random generator of QR_n"); 180166124Srafan capital_s = bi_new_ptr(); 181166124Srafan compute_generator_quadratic_residue(capital_s, n); 18250276Speter LogDebug("capital_s=%s", bi_2_hex_char(capital_s)); 18350276Speter 184166124Srafan // STEP 3 & 4 185166124Srafan LogDebug("Step 3 & 4 - compute group elements"); 18650276Speter product_PQprime = bi_new_ptr(); 187166124Srafan bi_mul( product_PQprime, pPrime, qPrime); 18850276Speter pair[ELEMENT] = bi_new_ptr(); 189174993Srafan pair[EXPONENT] = bi_new_ptr(); 19050276Speter 191174993Srafan LogDebug("product_PQprime=%s [%ld]", bi_2_hex_char(product_PQprime), 19250276Speter bi_nbin_size(product_PQprime)); 19350276Speter 19450276Speter compute_group_element(pair, capital_s, product_PQprime, n); 19550276Speter capital_z = bi_new_ptr(); 196166124Srafan bi_set(capital_z, pair[ELEMENT]); 19750276Speter xz = bi_new_ptr(); 19850276Speter bi_set(xz, pair[EXPONENT]); 199166124Srafan 20050276Speter // attributes bases 201166124Srafan compute_group_element(pair, capital_s, product_PQprime, n); 20250276Speter capital_r0 = bi_new_ptr(); 20350276Speter bi_set(capital_r0, pair[ELEMENT]); 20450276Speter x0 = bi_new_ptr(); 20550276Speter bi_set(x0, pair[EXPONENT]); 20650276Speter 207166124Srafan compute_group_element(pair, capital_s, product_PQprime, n); 20850276Speter capital_r1 = bi_new_ptr(); 20950276Speter bi_set(capital_r1, pair[ELEMENT]); 21050276Speter x1 = bi_new_ptr(); 21150276Speter bi_set(x1, pair[EXPONENT]); 212166124Srafan 21350276Speter // additional attribute bases 21450276Speter length = num_attributes_issuer + num_attributes_receiver; 215166124Srafan x = ALLOC_BI_ARRAY(); 216166124Srafan bi_new_array(x, length); 21750276Speter capital_r = ALLOC_BI_ARRAY(); 218166124Srafan bi_new_array(capital_r, length); 21950276Speter 22050276Speter for (i = 0; i < length; i++) { 221166124Srafan compute_group_element(pair, capital_s, product_PQprime, n); 222166124Srafan bi_set(capital_r->array[i], pair[ELEMENT]); 22350276Speter bi_set(x->array[i], pair[EXPONENT]); 224166124Srafan } 225166124Srafan 22650276Speter // split capitalR into Receiver and Issuer part 227166124Srafan capitalRReceiver = ALLOC_BI_ARRAY(); 22850276Speter bi_new_array2(capitalRReceiver, num_attributes_receiver); 22950276Speter for (i = 0; i < num_attributes_receiver; i++) 230166124Srafan capitalRReceiver->array[i] = capital_r->array[i]; 231166124Srafan capitalRIssuer = ALLOC_BI_ARRAY(); 23250276Speter bi_new_array2(capitalRIssuer, num_attributes_issuer); 23350276Speter for (i = 0; i < num_attributes_issuer; i++) 234166124Srafan capitalRIssuer->array[i] = capital_r->array[i + num_attributes_receiver]; 235166124Srafan 23650276Speter // STEP 6a 237184989Srafan LogDebug("Step 6"); 238184989Srafan gamma = bi_new_ptr(); 239184989Srafan capital_gamma = bi_new_ptr(); 240184989Srafan rho = bi_new_ptr(); 241184989Srafan r = bi_new_ptr(); 242184989Srafan rho_double = bi_new_ptr(); 243184989Srafan 244184989Srafan bi_generate_prime(rho, DAA_PARAM_SIZE_RHO); 245184989Srafan if (bi_length(rho) != DAA_PARAM_SIZE_RHO) { 246184989Srafan LogError("rho bit length=%ld", bi_length(rho)); 24750276Speter result = TSPERR(TSS_E_INTERNAL_ERROR); 24850276Speter goto close; 24950276Speter } 25050276Speter 25150276Speter do { 25250276Speter length = DAA_PARAM_SIZE_MODULUS_GAMMA - DAA_PARAM_SIZE_RHO; 25350276Speter do { 25450276Speter bi_urandom(r, length); 25550276Speter } while(bi_length(r) != length || bi_equals_si(bi_mod(bi_tmp, r, rho), 0)); 25650276Speter 25750276Speter // rho is not a dividor of r 25850276Speter bi_mul( capital_gamma, rho, r); 259166124Srafan // capital_gamma ++ 260166124Srafan bi_inc( capital_gamma); 261166124Srafan#ifdef DAA_DEBUG 26250276Speter if (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA) { 263166124Srafan printf("|"); fflush(stdout); 264166124Srafan } else { 26550276Speter printf("."); fflush(stdout); 266166124Srafan } 267166124Srafan#endif 26850276Speter } while (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA || 26950276Speter bi_is_probable_prime(capital_gamma) == 0 ); 270166124Srafan 27150276Speter // STEP 6b 27250276Speter if (bi_equals(bi_sub_si(bi_tmp, capital_gamma, 1), 273166124Srafan bi_mod(bi_tmp1, bi_mul(bi_tmp2, rho, r), n)) == 0) { 27450276Speter LogWarn("capital_gamma-1 != (rho * r) mod n tmp=%s tmp1=%s", 27550276Speter bi_2_hex_char(bi_tmp), bi_2_hex_char(bi_tmp1)); 27650276Speter } 27750276Speter 27850276Speter if (bi_equals(bi_div(bi_tmp, bi_sub_si(bi_tmp1, capital_gamma, 1), rho), r ) == 0) { 279166124Srafan LogWarn("( capital_gamma - 1)/rho != r"); 28050276Speter } 281166124Srafan 28250276Speter LogDebug("capital_gamma=%s\n", bi_2_hex_char(capital_gamma)); 283166124Srafan do { 28450276Speter compute_random_number_star(gamma, capital_gamma); 28550276Speter // gamma = (gamma ^ r) mod capital_gamma 28650276Speter bi_mod_exp(gamma, gamma, r, capital_gamma); 28750276Speter } while (bi_equals(gamma, bi_1)); 28850276Speter // STEP 7 28950276Speter buffer = (BYTE *)malloc(base_nameLength); 290166124Srafan if (buffer == NULL) { 291166124Srafan LogError("malloc of %u bytes failed", base_nameLength); 292166124Srafan result = TSPERR(TSS_E_OUTOFMEMORY); 293166124Srafan goto close; 294166124Srafan } 295166124Srafan memcpy(buffer, base_name, base_nameLength); 29650276Speter // all fields are linked to the struct with direct reference 29776726Speter public_key = create_DAA_PK(n, capital_s, capital_z, capital_r0, capital_r1, gamma, 298166124Srafan capital_gamma, rho, capitalRReceiver, capitalRIssuer, 299166124Srafan base_nameLength, buffer); 30050276Speter 30150276Speter // STEP 8 302174993Srafan // TODO dynamically load DAAKeyCorrectnessProof 303166124Srafan LogDebug("Step 8: generate proof (please wait: long process)"); 304166124Srafan TSS_DAA_PK_PROOF_internal *correctness_proof = generate_proof(product_PQprime, public_key, 30550276Speter xz, x0, x1, x); 30650276Speter if (correctness_proof == NULL) { 307174993Srafan LogError("creation of correctness_proof failed"); 30850276Speter result = TSPERR(TSS_E_OUTOFMEMORY); 309166124Srafan goto close; 31050276Speter } 31150276Speter 31250276Speter *key_pair_with_proof = (KEY_PAIR_WITH_PROOF_internal *) 31350276Speter malloc(sizeof(KEY_PAIR_WITH_PROOF_internal)); 31450276Speter if (*key_pair_with_proof == NULL) { 31550276Speter LogError("malloc of %zd bytes failed", sizeof(KEY_PAIR_WITH_PROOF_internal)); 31650276Speter result = TSPERR(TSS_E_OUTOFMEMORY); 31750276Speter goto close; 318166124Srafan } 319166124Srafan 32050276Speter (*key_pair_with_proof)->pk = public_key; 32150276Speter (*key_pair_with_proof)->proof = correctness_proof; 32250276Speter // all fields are linked to the struct with direct reference 32350276Speter (*key_pair_with_proof)->private_key = create_TSS_DAA_PRIVATE_KEY(pPrime, qPrime); 32450276Speterclose: 32550276Speter if (result != TSS_SUCCESS) { 32650276Speter // remove everything, even numbers that should be stored in a struct 32750276Speter FREE_BI(pPrime); // kept if no error 32850276Speter FREE_BI(qPrime); // kept if no error 32950276Speter FREE_BI(n); // kept if no error 33050276Speter // FREE_BI( p); 33150276Speter // FREE_BI( q); 33276726Speter FREE_BI(capital_s); // kept if no error 333166124Srafan FREE_BI(capital_z); // kept if no error 33450276Speter // FREE_BI(product_PQprime); 335166124Srafan // FREE_BI(pair[ELEMENT]); 336166124Srafan // FREE_BI(pair[EXPONENT]); 337166124Srafan // FREE_BI(xz); 33850276Speter FREE_BI(capital_r0); // kept if no error 33950276Speter // FREE_BI(x0); 340166124Srafan FREE_BI(capital_r1); // kept if no error 34150276Speter // FREE_BI( x1); 342166124Srafan // bi_array_ptr x = NULL; 343166124Srafan // bi_array_ptr capital_r = NULL; 344166124Srafan // bi_array_ptr capitalRReceiver = NULL; 34550276Speter // bi_array_ptr capitalRIssuer = NULL; 34650276Speter FREE_BI( gamma); // kept if no error 347166124Srafan FREE_BI( capital_gamma); // kept if no error 34850276Speter FREE_BI( rho); // kept if no error 34950276Speter // FREE_BI( r); 35050276Speter // FREE_BI( rho_double); 35150276Speter if (buffer!=NULL) 35250276Speter free(buffer); 35350276Speter 35450276Speter if (public_key != NULL) 35550276Speter free(public_key); 35650276Speter 357166124Srafan if (*key_pair_with_proof != NULL) 358166124Srafan free(*key_pair_with_proof); 359166124Srafan } 360166124Srafan /* 361166124Srafan Fields kept by structures 36250276Speter TSS_DAA_PK: n 36376726Speter capital_s 364166124Srafan capital_z 36550276Speter capital_r0 36650276Speter capital_r1 36750276Speter gamma 368166124Srafan capital_gamma 369166124Srafan rho 370166124Srafan capitalRReceiver 371166124Srafan capitalRIssuer 37250276Speter base_nameLength 37350276Speter buffer 374166124Srafan TSS_DAA_PRIVATE_KEY: 37550276Speter pPrime 376166124Srafan qPrime 37750276Speter */ 378166124Srafan bi_free(bi_tmp); 379166124Srafan bi_free(bi_tmp1); 380166124Srafan bi_free(bi_tmp2); 381166124Srafan FREE_BI(p); 382166124Srafan FREE_BI(q); 38350276Speter FREE_BI(product_PQprime); 38450276Speter FREE_BI(pair[ELEMENT]); 385166124Srafan FREE_BI(pair[EXPONENT]); 38650276Speter FREE_BI(xz); 38750276Speter FREE_BI(x0); 38850276Speter FREE_BI(x0); 38950276Speter // bi_array_ptr x = NULL; 39050276Speter // bi_array_ptr capital_r = NULL; 39150276Speter // bi_array_ptr capitalRReceiver = NULL; 39250276Speter // bi_array_ptr capitalRIssuer = NULL; 39350276Speter FREE_BI(r); 39476726Speter FREE_BI(rho_double); 395166124Srafan 39650276Speter return result; 397166124Srafan} 398166124Srafan