verifier_transaction.c revision 1.1
1
2/*
3 * Licensed Materials - Property of IBM
4 *
5 * trousers - An open source TCG Software Stack
6 *
7 * (C) Copyright International Business Machines Corp. 2006
8 *
9 */
10
11
12#include <stdlib.h>
13#include <stdio.h>
14#include <string.h>
15
16// for message digest
17#include <openssl/evp.h>
18
19#include "daa_structs.h"
20#include "daa_parameter.h"
21#include "trousers/tss.h"
22#include "spi_internal_types.h"
23#include "spi_utils.h"
24#include <trousers/trousers.h>
25#include <spi_utils.h>
26#include <obj.h>
27#include "tsplog.h"
28#include "tss/tcs.h"
29#include "verifier.h"
30
31#include "trousers/tss.h"
32#include "spi_internal_types.h"
33#include "spi_utils.h"
34
35#include "anonymity_revocation.h"
36
37DAA_VERIFIER_TRANSACTION *create_verifier_transaction( int length, char *base_name) {
38	DAA_VERIFIER_TRANSACTION *verifier_transaction =
39		malloc(sizeof(DAA_VERIFIER_TRANSACTION));
40
41	if (verifier_transaction == NULL) {
42		LogError("malloc of %d bytes failed", sizeof(DAA_VERIFIER_TRANSACTION));
43		return NULL;
44	}
45	verifier_transaction->baseName = base_name;
46	verifier_transaction->baseName_length = length;
47	OpenSSL_add_all_digests();
48	verifier_transaction->digest = DAA_PARAM_get_message_digest();
49	return verifier_transaction;
50}
51
52static int verifyNonce( BYTE *nonce_verifier, int length) {
53	//TODO check nonce_verifier with the current transaction nonce
54	return 1;
55}
56
57BYTE *compute_bytes( int seedLength, BYTE *seed, int length, const EVP_MD *digest) {
58	EVP_MD_CTX mdctx;
59	int N;
60	BYTE *hash;
61	BYTE *result;
62	int i, big_indian_i, len_hash;
63
64	result = (BYTE *)malloc( length);
65	if (result == NULL) {
66		LogError("malloc of %d bytes failed", length);
67		return NULL;
68	}
69	EVP_MD_CTX_init(&mdctx);
70	EVP_DigestInit_ex(&mdctx, digest, NULL);
71	len_hash = EVP_MD_size(digest);
72	N = length / len_hash;
73	hash = (BYTE *)malloc( len_hash);
74	if (hash == NULL) {
75		LogError("malloc of %d bytes failed", len_hash);
76		return NULL;
77	}
78	for( i=0; i<N; i++) {
79		EVP_DigestUpdate(&mdctx,  seed, seedLength);
80		big_indian_i = htonl( i);
81		EVP_DigestUpdate(&mdctx,  &big_indian_i, sizeof( int));
82		EVP_DigestFinal_ex(&mdctx, &result[ i * len_hash], NULL);
83		EVP_DigestInit_ex(&mdctx, digest, NULL);
84	}
85	// fill up the rest of the array (i=N)
86	EVP_DigestUpdate(&mdctx,  seed, seedLength);
87	big_indian_i = htonl( i);
88	EVP_DigestUpdate(&mdctx,  &big_indian_i, sizeof( int));
89	EVP_DigestFinal(&mdctx, hash, NULL);
90	// copy the rest:  base_nameLength % len_hash bytes
91	memcpy( &result[ i * len_hash], hash, length - N * len_hash);
92	free( hash);
93	return result;
94}
95
96/* from DAAUtil */
97bi_ptr project_into_group_gamma( bi_ptr base, TSS_DAA_PK_internal *issuer_pk) {
98	bi_t exponent; bi_new( exponent);
99	bi_ptr capital_gamma  = issuer_pk->capitalGamma;
100	bi_ptr rho = issuer_pk->rho;
101	bi_ptr zeta = bi_new_ptr();
102
103	if( capital_gamma == NULL ||
104		rho == NULL ||
105		zeta == NULL) return NULL;
106	// exponent = capital_gamma - 1
107	bi_sub( exponent, capital_gamma, bi_1);
108	// exponent = exponent / rho
109	bi_div( exponent, exponent, rho);
110	// zeta = ( base ^ exponent) % capital_gamma
111	LogDebug("project_into_group_gamma:           rho      [%ld]:%s",
112			bi_nbin_size( rho), bi_2_hex_char( rho));
113	LogDebug("project_into_group_gamma:               base[%ld]:%s",
114			bi_nbin_size( base), bi_2_hex_char( base));
115	LogDebug("project_into_group_gamma: exponent       [%ld]:%s",
116			bi_nbin_size( exponent), bi_2_hex_char( exponent));
117	LogDebug("project_into_group_gamma: capitalGamma[%ld]:%s",
118		bi_nbin_size( capital_gamma),
119		bi_2_hex_char( capital_gamma));
120	bi_mod_exp( zeta, base, exponent, capital_gamma);
121	LogDebug("project_into_group_gamma: result:%s", bi_2_hex_char( zeta));
122	bi_free( exponent);
123	return zeta;
124}
125
126bi_ptr compute_zeta( int nameLength, unsigned char *name, TSS_DAA_PK_internal *issuer_pk) {
127	BYTE *bytes;
128	bi_ptr base;
129	bi_ptr result;
130
131	LogDebug("compute_zeta: %d [%s] pk:%x", nameLength, name, (int)issuer_pk);
132	bytes = compute_bytes( nameLength,
133				name,
134				DAA_PARAM_LENGTH_MFG1_GAMMA,
135				DAA_PARAM_get_message_digest());
136	if( bytes == NULL) return NULL;
137	base = bi_set_as_nbin( DAA_PARAM_LENGTH_MFG1_GAMMA, bytes);
138	if( base == NULL) return NULL;
139	LogDebug("base: %ld [%s]", bi_nbin_size( base), bi_2_hex_char( base));
140	result = project_into_group_gamma( base, issuer_pk);
141	if( result == NULL) return NULL;
142	bi_free_ptr( base);
143	free( bytes);
144	LogDebug("return zeta:%s\n", bi_2_hex_char( result));
145	return result;
146}
147
148bi_ptr compute_parameterized_gamma(int k, TSS_DAA_PK_internal *issuer_pk) {
149	int length;
150	int hashLength = bi_nbin_size( issuer_pk->gamma) + sizeof(int);
151	BYTE *hash;
152	int big_indian_k = htonl( k);
153	BYTE *bytes;
154	bi_ptr value, result;
155
156	hash = (BYTE *)malloc( hashLength);
157	if (hash == NULL) {
158		LogError("malloc of %d bytes failed", hashLength);
159		return NULL;
160	}
161	// hash[0-3] = big_indian(k)
162	memcpy( hash, &big_indian_k, sizeof(int));
163	// hash[4-end] = issuer_pk->gamma
164	bi_2_nbin1( &length, &hash[sizeof(int)], issuer_pk->gamma);
165	// allocation
166	bytes = compute_bytes( hashLength, hash,
167				DAA_PARAM_LENGTH_MFG1_GAMMA,
168				DAA_PARAM_get_message_digest());
169	if( bytes == NULL) return NULL;
170	// allocation
171	value = bi_set_as_nbin( DAA_PARAM_LENGTH_MFG1_GAMMA, bytes);
172	if( value == NULL) return NULL;
173	result = project_into_group_gamma( value, issuer_pk); // allocation
174	if (result == NULL) {
175		LogError("malloc of %d bytes failed", hashLength);
176		return NULL;
177	}
178	bi_free_ptr( value);
179	free( bytes);
180	return result;
181}
182
183inline bi_ptr apply_challenge( bi_ptr value, bi_ptr delta, bi_ptr c, bi_ptr capital_gamma) {
184	bi_ptr delta_tilde = bi_new_ptr();
185	bi_t c_negate;
186
187	if( delta_tilde == NULL) return NULL;
188	bi_new( c_negate);
189	bi_set( c_negate, c);
190	bi_negate( c_negate);
191	// delta_tilde = ( delta ^ (-c)) % capital_gamma
192	bi_mod_exp( delta_tilde, delta, c_negate, capital_gamma);
193	bi_free( c_negate);
194	// delta_tilde = (delta_tilde * value) % capital_gamma
195	return bi_mod( delta_tilde, bi_mul( delta_tilde, delta_tilde, value), capital_gamma);
196}
197
198DAA_VERIFIER_TRANSACTION *createTransaction(int baseName_length, BYTE* baseName) {
199	DAA_VERIFIER_TRANSACTION *result =
200		(DAA_VERIFIER_TRANSACTION *)malloc( sizeof(DAA_VERIFIER_TRANSACTION));
201
202	if (result == NULL) {
203		LogError("malloc of %d bytes failed", sizeof(DAA_VERIFIER_TRANSACTION));
204		return NULL;
205	}
206	result->baseName = baseName;
207	result->baseName_length = baseName_length;
208	return result;
209}
210
211void update( EVP_MD_CTX *mdctx, char *name, bi_ptr integer, int bitLength) {
212	int length = bitLength / 8;
213	BYTE buffer[length];
214
215	bi_2_byte_array( buffer, length, integer);
216	LogDebug("[update] %s:%s", name, dump_byte_array( length, buffer));
217	EVP_DigestUpdate(mdctx, buffer, length);
218}
219
220BYTE *compute_sign_challenge_host(
221	int *result_length,
222	EVP_MD *digest,
223	TSS_DAA_PK_internal *issuer_pk,
224	int nonce_verifierLength,
225	BYTE *nonce_verifier,
226	int selected_attributes2commitLength,
227	TSS_DAA_SELECTED_ATTRIB **selected_attributes2commit,
228	int is_anonymity_revocation_enabled,
229	bi_ptr zeta,
230	bi_ptr capital_t,
231	bi_ptr capital_tilde,
232	int attribute_commitmentsLength,
233	TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitments,
234	TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitment_proofs,
235	bi_ptr capital_nv,
236	bi_ptr capital_tilde_v,
237	CS_PUBLIC_KEY *anonymity_revocator_pk,
238	CS_ENCRYPTION_RESULT *encryption_result_rand,
239	CS_ENCRYPTION_RESULT *encryption_result_proof
240) {
241	EVP_MD_CTX mdctx;
242	int i, length;
243	unsigned int big_indian;
244	BYTE *buffer;
245	int length_gamma_modulus;
246	BYTE *buffer1;
247
248	LogDebug("issuer_pk basename[%d]:%s",
249		issuer_pk->issuerBaseNameLength,
250		dump_byte_array( issuer_pk->issuerBaseNameLength,
251				issuer_pk->issuerBaseName));
252	LogDebug("nonce_verifier[%d]:%s",
253		nonce_verifierLength,
254		dump_byte_array( nonce_verifierLength, nonce_verifier));
255	LogDebug("selected_attributes2commitLength:%d", selected_attributes2commitLength);
256	LogDebug("is_anonymity_revocation_enabled:%d", is_anonymity_revocation_enabled);
257	LogDebug("zeta[%ld]:%s", bi_nbin_size( zeta), bi_2_hex_char( zeta));
258	LogDebug("capital_t[%ld]:%s", bi_nbin_size( capital_t), bi_2_hex_char( capital_t));
259	LogDebug("capital_tilde[%ld]:%s",
260		bi_nbin_size( capital_tilde),
261		bi_2_hex_char( capital_tilde));
262	LogDebug("attribute_commitmentsLength:%d", attribute_commitmentsLength);
263	LogDebug("attribute_commitments:%d", (int)attribute_commitments);
264	LogDebug("attribute_commitment_proofs:%d", (int)attribute_commitment_proofs);
265	LogDebug("capital_nv[%ld]:%s", bi_nbin_size( capital_nv), bi_2_hex_char( capital_nv));
266	LogDebug("capital_tilde_v[%ld]:%s",
267		bi_nbin_size( capital_tilde_v),
268		bi_2_hex_char( capital_tilde_v));
269	LogDebug("anonymity_revocator_pk:%d", (int)anonymity_revocator_pk);
270	LogDebug("encryption_result_rand:%d", (int)encryption_result_rand);
271	LogDebug("encryption_result_proof:%d", (int)encryption_result_proof);
272
273	EVP_MD_CTX_init(&mdctx);
274	EVP_DigestInit_ex(&mdctx, digest, NULL);
275	// update with encoded PK
276	buffer = encoded_DAA_PK_internal( &length, issuer_pk);
277	if( buffer == NULL) return NULL;
278	LogDebug("encoded issuer_pk[%d]:%s", length, dump_byte_array( length, buffer));
279	EVP_DigestUpdate(&mdctx, buffer , length);
280	free( buffer);
281	// nonce verifier
282	EVP_DigestUpdate(&mdctx, nonce_verifier , nonce_verifierLength);
283	// length Commitments
284	big_indian = attribute_commitmentsLength;
285	EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int));
286	// Anonymity enabled
287	big_indian = is_anonymity_revocation_enabled;
288	EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int));
289
290	update( &mdctx, "zeta", zeta, DAA_PARAM_SIZE_MODULUS_GAMMA);
291	update( &mdctx, "capitalT", capital_t, DAA_PARAM_SIZE_RSA_MODULUS);
292	update( &mdctx, "capitalTTilde", capital_tilde, DAA_PARAM_SIZE_RSA_MODULUS);
293
294	length_gamma_modulus = DAA_PARAM_SIZE_MODULUS_GAMMA / 8;
295	buffer = (BYTE *)malloc( length_gamma_modulus);// allocation
296	if (buffer == NULL) {
297		LogError("malloc of %d bytes failed", length_gamma_modulus);
298		return NULL;
299	}
300	if( selected_attributes2commitLength > 0) {
301		for( i=0; i<selected_attributes2commitLength; i++) {
302			buffer1 = to_bytes_TSS_DAA_SELECTED_ATTRIB_internal(
303				&length,
304				selected_attributes2commit[i]);
305			EVP_DigestUpdate(&mdctx, buffer1, length);
306			free( buffer1);
307			bi_2_byte_array( buffer,
308					length_gamma_modulus,
309					attribute_commitments[i]->beta);
310			EVP_DigestUpdate(&mdctx,
311					buffer,
312					length_gamma_modulus);
313			bi_2_byte_array( buffer,
314					length_gamma_modulus,
315					attribute_commitment_proofs[i]->beta);
316			EVP_DigestUpdate(&mdctx,
317					buffer,
318					length_gamma_modulus);
319		}
320	}
321	if( !is_anonymity_revocation_enabled) {
322		// Nv, N~v
323		bi_2_byte_array( buffer, length_gamma_modulus, capital_nv);
324		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
325		bi_2_byte_array( buffer, length_gamma_modulus, capital_tilde_v);
326		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
327	} else {
328		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->eta);
329		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
330		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda1);
331		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
332		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda2);
333		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
334		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda3);
335		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
336		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c1);
337		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
338		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c2);
339		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
340		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c3);
341		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
342		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c4);
343		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
344		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c1);
345		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
346		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c2);
347		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
348		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c3);
349		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
350		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c4);
351		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
352	}
353	free(buffer);
354	buffer = (BYTE *)malloc(EVP_MD_size(digest)); // allocation
355	if (buffer == NULL) {
356		LogError("malloc of %d bytes failed", EVP_MD_size(digest));
357		return NULL;
358	}
359	EVP_DigestFinal_ex(&mdctx, buffer, result_length);
360	EVP_MD_CTX_cleanup(&mdctx);
361	LogDebug("compute_sign_challenge_host[%d]:%s",
362		*result_length,
363		dump_byte_array( *result_length, buffer));
364	return buffer;
365}
366
367inline int is_element_gamma( bi_ptr capital_nv, TSS_DAA_PK_internal *issuer_pk) {
368	bi_ptr tmp1 = bi_new_ptr();
369	int result;
370
371	//	( ( capital_nv ^ issuer_pk->rho ) % issuer_pk->capitalGamma ) == 1
372	result = bi_equals( bi_mod_exp( tmp1,
373					capital_nv,
374					issuer_pk->rho,
375					issuer_pk->capitalGamma),
376				bi_1);
377	bi_free_ptr( tmp1);
378	return result;
379}
380
381/* implementation  derived from isValid (VerifierTransaction.java) */
382TSPICALL Tspi_DAA_VerifySignature_internal
383(	TSS_HDAA hDAA,	// in
384	TSS_DAA_SIGNATURE signature_ext, // in
385	TSS_HKEY hPubKeyIssuer,	// in
386	TSS_DAA_SIGN_DATA sign_data,	// in
387	UINT32 attributesLength,	// in
388	BYTE **attributes,	// in
389	UINT32 nonce_verifierLength,	// out
390	BYTE *nonce_verifier,	// out
391	UINT32 base_nameLength,	// out
392	BYTE *base_name,	// out
393	TSS_BOOL *isCorrect	// out
394) {
395	int i, j;
396	DAA_VERIFIER_TRANSACTION *verifier_transaction = NULL;
397	TSS_DAA_ATTRIB_COMMIT *commitments;
398	TSS_DAA_PK_internal *issuer_pk;
399	TSS_DAA_SIGNATURE_internal *signature = NULL;
400	bi_ptr tmp1;
401	bi_array_ptr sA;
402	bi_ptr n = NULL;
403	bi_ptr c = NULL;
404	bi_ptr capital_gamma = NULL;
405	bi_ptr zeta_2_verify = NULL;
406	bi_ptr capital_z = NULL;
407	bi_array_ptr capital_R = NULL;
408	bi_ptr product_r = NULL;
409	bi_ptr exp = NULL;
410	bi_ptr capital_THat = NULL;
411	bi_ptr beta_tilde = NULL;
412	bi_ptr gamma_i = NULL;
413	bi_ptr capital_nv = NULL;
414	bi_ptr capital_ntilde_v = NULL;
415	bi_ptr pseudonym_projected = NULL;
416	bi_ptr s_tau = NULL;
417	bi_ptr delta_tilde1 = NULL;
418	bi_ptr delta_tilde2 = NULL;
419	bi_ptr delta_tilde3 = NULL;
420	bi_ptr delta_tilde4 = NULL;
421	bi_ptr attribute_i;
422	TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain;
423	CS_ENCRYPTION_RESULT *pseudonym_enc = NULL;
424	CS_ENCRYPTION_RESULT *pseudonym_encryption_proof = NULL;
425	TSS_DAA_PSEUDONYM_ENCRYPTED_internal *sig_pseudonym_encrypted = NULL;
426	CS_ENCRYPTION_RESULT_RANDOMNESS *result_random = NULL;
427	CS_ENCRYPTION_RESULT *encryption_result = NULL;
428	TSS_DAA_ATTRIB_COMMIT_internal **commitment_proofs = NULL;
429	TCS_CONTEXT_HANDLE tcsContext;
430	TSS_RESULT result = TSS_SUCCESS;
431	EVP_MD_CTX mdctx;
432	int length_ch, len_hash, bits;
433	BYTE *ch = NULL, *hash = NULL;
434	TSS_BOOL *indices;
435
436	tmp1 = bi_new_ptr();
437	if( tmp1 == NULL) {
438		LogError("malloc of BI <%s> failed", "tmp1");
439		result = TSPERR(TSS_E_OUTOFMEMORY);
440		goto close;
441	}
442	*isCorrect = FALSE;
443	if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS)
444		goto close;
445	// allocation of issuer_pk
446	issuer_pk = e_2_i_TSS_DAA_PK( (TSS_DAA_PK *)hPubKeyIssuer);
447	if( issuer_pk == NULL) {
448		LogError("malloc of TSS_DAA_PK_internal failed");
449		result = TSPERR(TSS_E_OUTOFMEMORY);
450		goto close;
451	}
452	// allocation of signature
453	signature = e_2_i_TSS_DAA_SIGNATURE( &signature_ext);
454	if( signature == NULL) {
455		LogError("malloc of TSS_DAA_SIGNATURE_internal failed");
456		result = TSPERR(TSS_E_OUTOFMEMORY);
457		goto close;
458	}
459	commitments = signature_ext.attributeCommitments;
460	// TODO verify consistency of sig.getSA() with selectedAttributes,..
461	sA = signature->sA;
462	if( sA->length != (int)attributesLength) {
463		LogError("Verifier Error: lengths of attributes and sA must be equal");
464		result = TSS_E_BAD_PARAMETER;
465		goto close;
466	}
467	for ( i = 0; i < (int)attributesLength; i++) {
468		if ( (attributes[i] == NULL && bi_equals( sA->array[i], bi_0)) ||
469			(attributes[i] != NULL && !bi_equals( sA->array[i], bi_0))) {
470			LogError( "Verifier Error: illegal argument content in attributes\
471 and sA[%d]", i);
472			result = TSS_E_BAD_PARAMETER;
473			goto close;
474		}
475	}
476	// TODO: implement verify nonce
477	if ( verifyNonce(nonce_verifier, nonce_verifierLength) == 0) {
478		LogError("Verifier Error: nonce invalid");
479		result = TSS_E_INTERNAL_ERROR;
480		goto close;
481	}
482	n = issuer_pk->modulus;
483	c = bi_set_as_nbin( signature->challenge_length, signature->challenge);
484	capital_gamma = issuer_pk->capitalGamma;
485	if( base_name != NULL) { // isRandomBaseName
486		zeta_2_verify = compute_zeta( base_nameLength, base_name, issuer_pk);
487		if( bi_equals( signature->zeta, zeta_2_verify) == 0) {
488			LogError("Verifier Error: Verification of zeta failed - Step 1");
489			result = TSS_E_INTERNAL_ERROR;
490			goto close;
491		}
492	}
493	LogDebug( "step 2");
494	capital_z = issuer_pk->capitalZ;
495	capital_R = issuer_pk->capitalY;
496	product_r = bi_new_ptr();
497	if( product_r == NULL) {
498		LogError("malloc of BI <%s> failed", "product_r");
499		result = TSPERR(TSS_E_OUTOFMEMORY);
500		goto close;
501	}
502	bi_set( product_r, bi_1); // product_r = 1
503	for( i=0; i<(int)attributesLength; i++) {
504		if( attributes[i] != NULL) {
505			 // allocation
506			attribute_i = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, attributes[i]);
507			if( attribute_i == NULL) {
508				LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
509				result = TSPERR(TSS_E_OUTOFMEMORY);
510				goto close;
511			}
512			// tmp1 = (capital_R[i] ^ attributes[i]) mod n
513			bi_mod_exp( tmp1, capital_R->array[i], attribute_i, n);
514			// product_r = product_r * tmp1
515			bi_mul( product_r, product_r, tmp1);
516			// product_r = product_r mod n
517			bi_mod( product_r, product_r, n);
518			bi_free_ptr( attribute_i);
519		}
520	}
521	exp = bi_new_ptr();
522	if( exp == NULL) {
523		LogError("malloc of BI <%s> failed", "product_r");
524		result = TSPERR(TSS_E_OUTOFMEMORY);
525		goto close;
526	}
527	capital_THat = bi_new_ptr();
528	// tmp1 = product_r invmod n
529	bi_invert_mod( tmp1, product_r, n);
530	// capital_THat = capital_z * tmp1
531	bi_mul( capital_THat, capital_z, tmp1);
532	// capital_THat = capital_THat % n
533	bi_mod( capital_THat, capital_THat, n);
534	// capital_THat = (capital_THat ^ (-c)) mod n = ( 1 / (capital_That ^ c) ) % n
535	bi_mod_exp( capital_THat, capital_THat, c, n);
536	bi_invert_mod( capital_THat, capital_THat, n);
537	// tmp1 = c << (SizeExponentCertificate - 1)
538	bi_shift_left( tmp1, c, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1);
539	// exp = signature->sE + tmp1
540	bi_add( exp, signature->sE, tmp1);
541	// tmp1 = (signature->capitalT ^ exp) mod n
542	bi_mod_exp( tmp1, signature->capitalT, exp, n);
543	//  capital_THat = ( capital_THat * tmp1 ) % n
544	bi_mul( capital_THat, capital_THat, tmp1);
545	bi_mod( capital_THat, capital_THat, n);
546	// tmp1=( issuer_pk->capitalR0 ^ signature->sF0) %  n
547	bi_mod_exp( tmp1, issuer_pk->capitalR0, signature->sF0, n);
548	//  capital_THat = ( capital_THat * tmp1 ) % n
549	bi_mul( capital_THat, capital_THat, tmp1);
550	bi_mod( capital_THat, capital_THat, n);
551	// tmp1=( issuer_pk->capitalR1 ^ signature->sF1) %  n
552	bi_mod_exp( tmp1, issuer_pk->capitalR1, signature->sF1, n);
553	//  capital_THat = ( capital_THat * tmp1 ) % n
554	bi_mul( capital_THat, capital_THat, tmp1);
555	bi_mod( capital_THat, capital_THat, n);
556	// tmp1=( issuer_pk->capitalS ^ signature->sV) %  n
557	bi_mod_exp( tmp1, issuer_pk->capitalS, signature->sV, n);
558	//  capital_THat = ( capital_THat * tmp1 ) % n
559	bi_mul( capital_THat, capital_THat, tmp1);
560	bi_mod( capital_THat, capital_THat, n);
561
562	bi_set( product_r, bi_1);	// product_r = 1
563	for( i=0; i<(int)attributesLength; i++) {
564		if( attributes[i] == NULL) {
565			// tmp1=(capital_R->array[i] ^ sA->array[i]) %  n
566			bi_mod_exp( tmp1, capital_R->array[i], sA->array[i], n);
567			//  product_r = ( product_r * tmp1 ) % n
568			bi_mul( product_r, product_r, tmp1);
569			bi_mod( product_r, product_r, n);
570		}
571	}
572	// capital_THat = (capital_THat * product_r) % n
573	bi_mod( capital_THat, bi_mul( tmp1, capital_THat, product_r), n);
574	LogDebug("Step 3 - Commitments");
575
576	//TODO when enabling the commitment feature, verifier_transaction should be set
577	#ifdef ANONYMITY_REVOCATION
578	if( verifier_transaction != NULL &&
579	    verifier_transaction->selected_attributes2commitLength > 0) {
580		commitment_proofs = (TSS_DAA_ATTRIB_COMMIT_internal **)
581			malloc(verifier_transaction->selected_attributes2commitLength *
582					sizeof(TSS_DAA_ATTRIB_COMMIT_internal*));
583		if (commitment_proofs == NULL) {
584			LogError("malloc of %d bytes failed",
585				verifier_transaction->selected_attributes2commitLength *
586				sizeof(TSS_DAA_ATTRIB_COMMIT_internal*));
587			result = TSPERR(TSS_E_OUTOFMEMORY);
588			goto close;
589		}
590		for( j=0; j<verifier_transaction->selected_attributes2commitLength; j++) {
591			if( bi_cmp( commitments[j].sMu, issuer_pk->rho) >= 0 ||
592					 bi_cmp_si( commitments[j].sMu, 0) < 0) {
593				LogError("sMu >= rho || sMu  < 0");
594				result = TSS_E_INTERNAL_ERROR;
595				goto close;
596			}
597			beta_tilde = bi_new_ptr();
598			if( beta_tilde == NULL) {
599				LogError("malloc of BI <%s> failed", "beta_tilde");
600				result = TSPERR(TSS_E_OUTOFMEMORY);
601				goto close;
602			}
603			bi_set( tmp1, c);
604			bi_negate( tmp1);
605			// beta_tilde=(commitments[j]->beta ^ (-c)) % capitalGamma
606			bi_mod_exp( beta_tilde,  commitments[j]->beta, tmp1, capital_gamma);
607			// tmp1=(issuer_pk->gamma ^ commitments[j]->sMu) % capital_gamma
608			bi_mod_exp( tmp1, issuer_pk->gamma, commitments[j]->sMu, capital_gamma);
609			// beta_tilde=beta_tilde * tmp1
610			bi_mul( beta_tilde, beta_tilde, tmp1);
611			// beta_tilde=beta_tilde % capital_gamma
612			bi_mod( beta_tilde, beta_tilde, capital_gamma);
613			indices = (verifier_transaction->selected_attributes2commit[j])->
614				indicesList;
615			if( verifier_transaction->selected_attributes2commit[j]->
616				indicesListLength != (UINT32)(issuer_pk->capitalY->length) ) {
617				LogError("indicesList of selected_attribs[%d] (%d) \
618and issuer_pk are not consistent (%d)\n",
619					j,
620					verifier_transaction->selected_attributes2commit[j]->
621									indicesListLength,
622					issuer_pk->capitalY->length);
623				result = TSS_E_INTERNAL_ERROR;
624				goto close;
625			}
626			for( i=0; i<issuer_pk->capitalY->length; i++) {
627				if( indices[i]) {
628					gamma_i = compute_parameterized_gamma( i, issuer_pk);
629					if( gamma_i == NULL) {
630						LogError("malloc of BI <%s> failed", "gamma_i");
631						result = TSPERR(TSS_E_OUTOFMEMORY);
632						goto close;
633					}
634					// tmp1=(gamma_i ^ sA[j]) % capital_gamma
635					bi_mod_exp( tmp1, gamma_i, sA->array[i], capital_gamma);
636					// beta_tilde=beta_tilde * tmp1
637					bi_mul( beta_tilde, beta_tilde, tmp1);
638					// beta_tilde=beta_tilde % capital_gamma
639					bi_mod( beta_tilde, beta_tilde, capital_gamma);
640				}
641			}
642			commitment_proofs[j] = create_TSS_DAA_ATTRIB_COMMIT( beta_tilde, NULL);
643		}
644	}
645	#endif
646	LogDebug("Step 4 - Pseudonym");
647	capital_nv = bi_new_ptr();
648	if( capital_nv == NULL) {
649		LogError("malloc of BI <%s> failed", "capital_nv");
650		result = TSPERR(TSS_E_OUTOFMEMORY);
651		goto close;
652	}
653	capital_ntilde_v = bi_new_ptr();
654	if( capital_ntilde_v == NULL) {
655		LogError("malloc of BI <%s> failed", "capital_ntilde_v");
656		result = TSPERR(TSS_E_OUTOFMEMORY);
657		goto close;
658	}
659	bi_shift_left( tmp1, signature->sF1, DAA_PARAM_SIZE_F_I);
660	bi_add( exp, signature->sF0, tmp1);
661	pseudonym_projected = bi_new_ptr();
662	// pseudonym_projected = (signature->zeta ^ exp) % capital_gamma
663	bi_mod_exp( pseudonym_projected, signature->zeta, exp, capital_gamma);
664	pseudonym_enc = NULL;
665	pseudonym_encryption_proof = NULL;
666	//TODO when enabling the commitment feature, verifier_transaction should be set
667	if( verifier_transaction == NULL ||
668		verifier_transaction->is_anonymity_revocation_enabled ==0) {
669		// anonymity revocation not enabled
670		pseudonym_plain = (TSS_DAA_PSEUDONYM_PLAIN *)signature_ext.signedPseudonym;
671		capital_nv = bi_set_as_nbin( pseudonym_plain->capitalNvLength,
672							pseudonym_plain->capitalNv);
673//TODO
674		// capital_ntilde_v = ( capital_nv ^ ( - c) ) % capital_gamma
675		//		= ( 1 / (capital_nv ^ c) % capital_gamma) % capital_gamma
676		bi_mod_exp( tmp1, capital_nv, c, capital_gamma);
677		bi_invert_mod( capital_ntilde_v, tmp1, capital_gamma);
678		// capital_ntilde_v = ( capital_ntilde_v * pseudonym_projected ) % capital_gamma
679		bi_mul(capital_ntilde_v, capital_ntilde_v, pseudonym_projected);
680		bi_mod( capital_ntilde_v, capital_ntilde_v, capital_gamma);
681	} else {
682#ifdef ANONYMITY_REVOCATION
683		// anonymity revocation enabled
684		sig_pseudonym_encrypted = (TSS_DAA_PSEUDONYM_ENCRYPTED_internal *)pseudonym;
685		s_tau = sig_pseudonym_encrypted->sTau;
686		pseudonym_enc = sig_pseudonym_encrypted->cs_enc_result;
687		// Note: It verifies if s_tau <= rho
688		result_random = compute_ecryption_proof(
689			pseudonym_projected,
690			pseudonym_enc->c1,
691			pseudonym_enc->c2,
692			pseudonym_enc->c3,
693			s_tau,
694			verifier_transaction->anonymity_revocator_pk, issuer_pk,
695			verifier_transaction->anonymity_revocation_condition,
696			verifier_transaction->anonymity_revocation_condition_length,
697			DAA_PARAM_get_message_digest() );
698		encryption_result = result_random->result;
699		delta_tilde1 = apply_challenge( encryption_result->c1,
700								pseudonym_enc->c1,
701								c,
702								capital_gamma);
703		delta_tilde2 = apply_challenge( encryption_result->c2,
704								pseudonym_enc->c2,
705								c,
706								capital_gamma);
707		delta_tilde3 = apply_challenge( encryption_result->c3,
708								pseudonym_enc->c3,
709								c,
710								capital_gamma);
711		delta_tilde4 = apply_challenge( encryption_result->c4,
712								pseudonym_enc->c4,
713								c,
714								capital_gamma);
715		pseudonym_encryption_proof = create_CS_ENCRYPTION_RESULT( delta_tilde1,
716														delta_tilde2,
717														delta_tilde3,
718														delta_tilde4);
719#endif
720	}
721
722	// TODO: Step 5 - Callback
723	LogDebug("Step 5 - Callback");
724
725	LogDebug("Step 6 - Hash");
726	ch = compute_sign_challenge_host(
727		&length_ch,
728		DAA_PARAM_get_message_digest(),
729		issuer_pk,
730		nonce_verifierLength,
731		nonce_verifier,
732		0, // verifier_transaction->selected_attributes2commitLength,
733		NULL, //verifier_transaction->selected_attributes2commit,
734		0, // verifier_transaction->is_anonymity_revocation_enabled,
735		signature->zeta,
736		signature->capitalT,
737		capital_THat,
738		0, //signature_ext.attributeCommitmentsLength,
739		NULL, // signature_ext.attributeCommitments,
740		commitment_proofs,
741		capital_nv,
742		capital_ntilde_v,
743		NULL, // verifier_transaction->anonymity_revocator_pk,
744		pseudonym_enc,
745		pseudonym_encryption_proof);
746	LogDebug("calculation of c: ch[%d]%s", length_ch, dump_byte_array( length_ch, ch));
747	LogDebug("calculation of c: nonce_tpm[%d]%s",
748			signature->nonce_tpm_length,
749			dump_byte_array( signature->nonce_tpm_length, signature->nonce_tpm));
750	LogDebug("calculation of c: sign_data.payloadFlag[%d]%x", 1, sign_data.payloadFlag);
751	LogDebug("calculation of c: signdata.payload[%d]%s",
752			sign_data.payloadLength,
753			dump_byte_array( sign_data.payloadLength, sign_data.payload));
754	EVP_MD_CTX_init(&mdctx);
755	EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
756	EVP_DigestUpdate(&mdctx, ch, length_ch);
757	EVP_DigestUpdate(&mdctx, signature->nonce_tpm, signature->nonce_tpm_length);
758	len_hash = EVP_MD_size( DAA_PARAM_get_message_digest());
759	hash = (BYTE *)malloc( len_hash);// allocation
760	if (hash == NULL) {
761		LogError("malloc of %d bytes failed", len_hash);
762		result = TSPERR(TSS_E_OUTOFMEMORY);
763		goto close;
764	}
765	EVP_DigestFinal_ex(&mdctx, hash, NULL);
766	EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
767	EVP_DigestUpdate(&mdctx, hash, EVP_MD_size( DAA_PARAM_get_message_digest()));
768	EVP_DigestUpdate(&mdctx, &sign_data.payloadFlag, 1);
769	EVP_DigestUpdate(&mdctx,  sign_data.payload, sign_data.payloadLength);
770	len_hash = EVP_MD_size( DAA_PARAM_get_message_digest());
771	free( hash);
772	hash = (BYTE *)malloc( len_hash);// allocation
773	if (hash == NULL) {
774		LogError("malloc of %d bytes failed", len_hash);
775		result = TSPERR(TSS_E_OUTOFMEMORY);
776		goto close;
777	}
778	EVP_DigestFinal(&mdctx, hash, NULL);
779
780	if( signature->challenge_length != len_hash ||
781		memcmp( signature->challenge, hash, len_hash) != 0) {
782		LogError( "Verification of c failed - Step 6.c.i");
783		LogError(" - challenge[%d] : %s",
784				signature->challenge_length,
785				dump_byte_array( signature->challenge_length, signature->challenge));
786		LogError(" -        hash[%d] : %s",
787				len_hash,
788				dump_byte_array( len_hash, hash));
789		result = TSS_E_INTERNAL_ERROR;
790		goto close;
791	}
792	if( verifier_transaction == NULL ||
793		 !verifier_transaction->is_anonymity_revocation_enabled) {
794		// Nv element <gamma> ?
795		if( !is_element_gamma( capital_nv, issuer_pk)	) {
796			LogError( "Verification of Nv failed - Step 4.b.i");
797			result = TSS_E_INTERNAL_ERROR;
798			goto close;
799		}
800	} else {
801		// are delta1-4 element <gamma> ?
802		if( !(	is_element_gamma( pseudonym_enc->c1, issuer_pk) &&
803			is_element_gamma( pseudonym_enc->c2, issuer_pk) &&
804			is_element_gamma( pseudonym_enc->c3, issuer_pk) &&
805			is_element_gamma( pseudonym_enc->c4, issuer_pk))) {
806			LogError( "Verification of delta1-4 failed - Step 4.c.i");
807			result = TSS_E_INTERNAL_ERROR;
808			goto close;
809		}
810	}
811	// zeta element <gamma>
812	if( !is_element_gamma( signature->zeta, issuer_pk)) {
813		LogError( "Verification of zeta failed - Step 4.b/c.i");
814		result = TSS_E_INTERNAL_ERROR;
815		goto close;
816	}
817	bits = DAA_PARAM_SIZE_F_I + DAA_PARAM_SAFETY_MARGIN +
818			DAA_PARAM_SIZE_MESSAGE_DIGEST + 1;
819	if( bi_length( signature->sF0) > bits) {
820		LogError("Verification of sF0 failed - Step 6.c.ii");
821		result = TSS_E_INTERNAL_ERROR;
822		goto close;
823	}
824	if( bi_length( signature->sF1) > bits) {
825		LogError("Verification of sF1 failed - Step 6.c.ii");
826		result = TSS_E_INTERNAL_ERROR;
827		goto close;
828	}
829	// attributes extension
830	for( i=0; i<sA->length; i++) {
831		if( sA->array[i] != NULL && bi_length(sA->array[i]) > bits) {
832			LogError( "Verification of sA[%d] failed - Step 6.c.ii", i);
833			result = TSS_E_INTERNAL_ERROR;
834			goto close;
835		}
836	}
837	bits = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE +
838			DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST + 1;
839	if( bi_length( signature->sE) > bits) {
840		LogError("Verification of sE failed - Step 6.c.iii");
841		result = TSS_E_INTERNAL_ERROR;
842		goto close;
843	}
844	// step 4
845	// TODO: implement revocation list
846	*isCorrect = TRUE;
847close:
848	bi_free_ptr( tmp1);
849	if( ch != NULL) free( ch);
850	if( hash != NULL) free( hash);
851	free_TSS_DAA_PK_internal( issuer_pk);
852	free_TSS_DAA_SIGNATURE_internal( signature);
853	// n not allocated, refere to issuer_pk->modulus
854	FREE_BI( c);
855	// capital_gamma not allocated, refere to issuer_pk->capitalGamma
856	FREE_BI( zeta_2_verify);
857	// capital_z not allocated, refere to issuer_pk->capitalZ
858	// capital_R not allocated, refere to issuer_pk->capitalY
859	FREE_BI( product_r);
860	FREE_BI( exp);
861	FREE_BI( capital_THat);
862	// beta_tilde kept on TSS_DAA_ATTRIB_COMMIT
863	FREE_BI( gamma_i);
864	FREE_BI( capital_nv);
865	FREE_BI( capital_ntilde_v);
866	FREE_BI( pseudonym_projected);
867	FREE_BI( s_tau);
868	// delta_tilde1 kept on CS_ENCRYPTION_RESULT
869	// delta_tilde2 kept on CS_ENCRYPTION_RESULT
870	// delta_tilde3 kept on CS_ENCRYPTION_RESULT
871	// delta_tilde4 kept on CS_ENCRYPTION_RESULT
872	return result;
873}
874