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