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