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