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 <stdlib.h>
20 #include "daa_structs.h"
21 #include "daa_parameter.h"
22 #include "trousers/tss.h"
23 #include "spi_internal_types.h"
24 #include "spi_utils.h"
25 #include <trousers/trousers.h>
26 #include <spi_utils.h>
27 #include <obj.h>
28 #include "tsplog.h"
29 #include "tss/tcs.h"
30 #include "platform.h"
31 // to include compute_zeta
32 #include "verifier.h"
33 
34 // from UBigInteger (computePrime)
35 // remark: the type bi_t (bi_ptr) can not used a certaintity for probable_prime
36 // as used in UbigInteger. (certaintity: DAA_PARAM_SAFETY)
compute_prime(bi_ptr e,int length,int interval)37 void compute_prime( bi_ptr e, int length, int interval) {
38           do {
39                     bi_urandom( e, interval - 1);
40                     bi_setbit( e, length - 1);
41           } while( bi_is_probable_prime( e) == 0);
42 }
43 
44 /*
45  code derived from verifyAuthenticity (IssuerTransaction.java)
46 */
verify_authentificity(TSS_DAA_CREDENTIAL_REQUEST * credentialRequest,TSS_DAA_JOIN_ISSUER_SESSION * joinSession)47 TSS_RESULT verify_authentificity(TSS_DAA_CREDENTIAL_REQUEST *credentialRequest,
48                                                             TSS_DAA_JOIN_ISSUER_SESSION *joinSession) {
49           EVP_MD_CTX *mdctx;
50           BYTE *modulus_N0_bytes;
51           BYTE *digest_n0;
52           BYTE *contextHash;
53           BYTE *capitalUPrime_bytes;
54           BYTE *hash;
55           UINT32 digest_n0Length, contextHashLength, hashLength, daaCount;
56           bi_ptr capitalUPrime  =NULL;
57           bi_ptr modulus_N0 = NULL;
58           TSS_RESULT result = TSS_SUCCESS;
59           char *buffer;
60 
61           modulus_N0 = bi_new_ptr();
62           buffer = BN_bn2hex( ((RSA *)joinSession->issuerAuthPK)->n);
63           if( buffer == NULL) {
64                     LogError("malloc of hexadecimal representation failed");
65                     result = TSPERR(TSS_E_OUTOFMEMORY);
66                     goto close;
67           }
68           bi_set_as_hex( modulus_N0, buffer);
69           // in TPM, N0 is hashed by hashing the scratch (256 bytes) so it must
70           // be formatted according to the scratch size (TPM_DAA_SIZE_issuerModulus)
71           modulus_N0_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus);
72           if (modulus_N0_bytes == NULL) {
73                     LogError("malloc of %d bytes failed", TPM_DAA_SIZE_issuerModulus);
74                     result = TSPERR(TSS_E_OUTOFMEMORY);
75                     goto close;
76           }
77           bi_2_byte_array( modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus, modulus_N0);
78           bi_free_ptr( modulus_N0);
79 
80           if( TPM_DAA_SIZE_issuerModulus * 8 != DAA_PARAM_KEY_SIZE) {
81                     LogError("TPM_DAA_SIZE_issuerModulus * 8 (%d) != DAA_PARAM_KEY_SIZE(%d)",
82                                TPM_DAA_SIZE_issuerModulus*8, DAA_PARAM_KEY_SIZE);
83                     return TSS_E_INTERNAL_ERROR;
84           }
85           mdctx = EVP_MD_CTX_create();
86           EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
87           // digestN0 = hash( modulus_N0) see Appendix B of spec. and TPM join stage 7 and 8
88           EVP_DigestUpdate(mdctx,  modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus);
89           digest_n0Length = EVP_MD_CTX_size(mdctx);
90           digest_n0 = (BYTE *)malloc( digest_n0Length);
91           if (digest_n0 == NULL) {
92                     LogError("malloc of %d bytes failed", digest_n0Length);
93                     result = TSPERR(TSS_E_OUTOFMEMORY);
94                     goto close;
95           }
96           EVP_DigestFinal(mdctx, digest_n0, NULL);
97 
98           // test if credentialRequest->authenticationProof =
99           //                                      H( H( U, daaCount, H(n0), joinSession->nonceEncrypted))
100           EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
101           // enlarge capitalU to 256 (TPM_DAA_SIZE_issuerModulus)
102            // allocation
103           capitalUPrime = bi_set_as_nbin( joinSession->capitalUprimeLength, joinSession->capitalUprime);
104           capitalUPrime_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus);
105           if (capitalUPrime_bytes == NULL) {
106                     LogError("malloc of %d bytes failed", TPM_DAA_SIZE_issuerModulus);
107                     result = TSPERR(TSS_E_OUTOFMEMORY);
108                     goto close;
109           }
110           bi_2_byte_array( capitalUPrime_bytes, TPM_DAA_SIZE_issuerModulus, capitalUPrime);
111           EVP_DigestUpdate(mdctx,  capitalUPrime_bytes, TPM_DAA_SIZE_issuerModulus);
112           bi_free_ptr( capitalUPrime);
113           daaCount = htonl( joinSession->daaCounter);
114           EVP_DigestUpdate(mdctx,  &daaCount, sizeof(UINT32));
115           EVP_DigestUpdate(mdctx,  digest_n0, digest_n0Length);
116           contextHashLength = EVP_MD_CTX_size(mdctx);
117           contextHash = (BYTE *)malloc( contextHashLength);
118           if (contextHash == NULL) {
119                     LogError("malloc of %d bytes failed", contextHashLength);
120                     result = TSPERR(TSS_E_OUTOFMEMORY);
121                     goto close;
122           }
123           EVP_DigestFinal(mdctx, contextHash, NULL);
124           EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
125           LogDebug("PK(0).n=%s", dump_byte_array( TPM_DAA_SIZE_issuerModulus, modulus_N0_bytes));
126           LogDebug("digestN0h=%s", dump_byte_array( digest_n0Length, digest_n0));
127           LogDebug("UPrime=%s", dump_byte_array( TPM_DAA_SIZE_issuerModulus, capitalUPrime_bytes));
128           LogDebug("daaCount=%4x", daaCount);
129 
130           LogDebug("contextHash[%d]=%s", contextHashLength, dump_byte_array( contextHashLength, contextHash));
131           EVP_DigestUpdate(mdctx,  contextHash, contextHashLength);
132           EVP_DigestUpdate(mdctx,  joinSession->nonceEncrypted, joinSession->nonceEncryptedLength);
133           hashLength = EVP_MD_CTX_size(mdctx);
134           hash = (BYTE *)malloc( hashLength);
135           if (hash == NULL) {
136                     LogError("malloc of %d bytes failed", hashLength);
137                     result = TSPERR(TSS_E_OUTOFMEMORY);
138                     goto close;
139           }
140           EVP_DigestFinal(mdctx, hash, NULL);
141           if( credentialRequest->authenticationProofLength != hashLength ||
142                     memcmp( credentialRequest->authenticationProof, hash, hashLength) != 0) {
143                     LogError("Verification of authenticationProof failed - Step 2.b");
144                     LogError("credentialRequest->authenticationProof[%d]=%s",
145                               credentialRequest->authenticationProofLength,
146                               dump_byte_array( credentialRequest->authenticationProofLength,
147                                         credentialRequest->authenticationProof));
148                     LogError("internal cByte[%d]=%s",
149                               hashLength,
150                               dump_byte_array( hashLength, hash));
151                     result = TSS_E_DAA_AUTHENTICATION_ERROR;
152                     goto close;
153           } else
154                     LogDebug("verify_authenticity Done:%s",
155                               dump_byte_array( hashLength, hash));
156 close:
157           EVP_MD_CTX_destroy(mdctx);
158           free( contextHash);
159           free( digest_n0);
160           free( capitalUPrime_bytes);
161           free( hash);
162           return result;
163 }
164 
165 TSS_RESULT
compute_join_challenge_issuer(TSS_DAA_PK_internal * pk_intern,bi_ptr v_prime_prime,bi_ptr capitalA,bi_ptr capital_Atilde,UINT32 nonceReceiverLength,BYTE * nonceReceiver,UINT32 * c_primeLength,BYTE ** c_prime)166 compute_join_challenge_issuer( TSS_DAA_PK_internal *pk_intern,
167                                                                       bi_ptr v_prime_prime,
168                                                                       bi_ptr capitalA,
169                                                                       bi_ptr capital_Atilde,
170                                                                       UINT32 nonceReceiverLength,
171                                                                       BYTE *nonceReceiver,
172                                                                       UINT32 *c_primeLength,
173                                                                       BYTE **c_prime) { // out allocation
174           EVP_MD_CTX *mdctx;
175           BYTE *encoded_pk;
176           BYTE *byte_array;
177           UINT32 encoded_pkLength;
178 
179           byte_array = (BYTE *)malloc( DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8); // allocation
180           if (byte_array == NULL) {
181                     LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8);
182                     return TSPERR(TSS_E_OUTOFMEMORY);
183           }
184           mdctx = EVP_MD_CTX_create();
185           EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
186           encoded_pk = encoded_DAA_PK_internal( &encoded_pkLength, pk_intern);
187           EVP_DigestUpdate(mdctx,  encoded_pk, encoded_pkLength);
188           LogDebug( "issuerPk: %s", dump_byte_array( encoded_pkLength, encoded_pk));
189           bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8, v_prime_prime);
190           EVP_DigestUpdate(mdctx, byte_array, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8);
191           LogDebug( "vPrimePrime: %s",
192                               dump_byte_array( DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8, byte_array));
193           free( byte_array);
194           // allocation
195           byte_array = (BYTE *)malloc( DAA_PARAM_SIZE_RSA_MODULUS / 8);
196           if (byte_array == NULL) {
197                     LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_RSA_MODULUS / 8);
198                     return TSPERR(TSS_E_OUTOFMEMORY);
199           }
200           bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8, capitalA);
201           EVP_DigestUpdate(mdctx, byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8);
202           LogDebug( "capitalA: %s", dump_byte_array( DAA_PARAM_SIZE_RSA_MODULUS / 8, byte_array));
203           bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8, capital_Atilde);
204           EVP_DigestUpdate(mdctx, byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8);
205           LogDebug( "capital_Atilde: %s",
206                               dump_byte_array( DAA_PARAM_SIZE_RSA_MODULUS / 8, byte_array));
207           EVP_DigestUpdate(mdctx, nonceReceiver, nonceReceiverLength);
208           LogDebug( "nonceReceiver: %s",
209                               dump_byte_array( nonceReceiverLength, nonceReceiver));
210           *c_primeLength = EVP_MD_CTX_size(mdctx);
211           *c_prime = (BYTE *)malloc( *c_primeLength);
212           if (*c_prime == NULL) {
213                     LogError("malloc of %d bytes failed", *c_primeLength);
214                     free( byte_array);
215                     return TSPERR(TSS_E_OUTOFMEMORY);
216           }
217           LogDebug( "c_prime: %s", dump_byte_array( *c_primeLength, *c_prime));
218           EVP_DigestFinal(mdctx, *c_prime, NULL);
219           EVP_MD_CTX_destroy(mdctx);
220           free( byte_array);
221           return TSS_SUCCESS;
222 }
223 
224 // inspired by computeCredentialProof (IssuerTransaction.java)
225 TSS_RESULT
compute_credential_proof(TSS_DAA_PK_internal * pk_intern,bi_ptr capital_A,bi_ptr fraction_A,bi_ptr eInverse,bi_ptr v_prime_prime,bi_ptr productPQprime,UINT32 noncePlatformLength,BYTE * noncePlatform,bi_ptr * c_prime,bi_ptr * s_e)226 compute_credential_proof( TSS_DAA_PK_internal *pk_intern,
227                                                             bi_ptr capital_A,
228                                                             bi_ptr fraction_A,
229                                                             bi_ptr eInverse,
230                                                             bi_ptr v_prime_prime,
231                                                             bi_ptr productPQprime,
232                                                             UINT32 noncePlatformLength,
233                                                             BYTE *noncePlatform,
234                                                             bi_ptr *c_prime,    // out
235                                                             bi_ptr *s_e         // out
236 ) {
237           bi_ptr random_E = bi_new_ptr();
238           bi_ptr capital_Atilde = bi_new_ptr();
239           BYTE *c_prime_bytes;
240           UINT32 c_primeLength;
241 
242           bi_urandom( random_E, bi_length( productPQprime) + DAA_PARAM_SAFETY_MARGIN * 8);
243           bi_mod( random_E, random_E, productPQprime);
244           bi_inc( random_E);
245           bi_mod_exp( capital_Atilde, fraction_A, random_E, pk_intern->modulus);
246           compute_join_challenge_issuer( pk_intern,
247                                                                                 v_prime_prime,
248                                                                                 capital_A,
249                                                                                 capital_Atilde,
250                                                                                 noncePlatformLength,
251                                                                                 noncePlatform,
252                                                                                 &c_primeLength,
253                                                                                 &c_prime_bytes); // allocation
254           *c_prime = bi_set_as_nbin( c_primeLength, c_prime_bytes); // allocation
255           *s_e = bi_new_ptr();
256           bi_mul( *s_e, *c_prime, eInverse);
257           bi_mod( *s_e, *s_e, productPQprime);
258           bi_sub( *s_e, random_E, *s_e);
259           bi_mod( *s_e, *s_e, productPQprime);
260           bi_free_ptr( capital_Atilde);
261           bi_free_ptr( random_E);
262           free( c_prime_bytes);
263           return TSS_SUCCESS;
264 }
265 
266 // from IssuerTransaction.java (joinStep2)
267 // stacks: TCGApplication.java (retrieveDAACredential) -> Issuer.java(issueCredential)
Tspi_DAA_IssueCredential_internal(TSS_HDAA hDAA,UINT32 attributesIssuerLength,BYTE ** attributesIssuer,TSS_DAA_CREDENTIAL_REQUEST credentialRequest,TSS_DAA_JOIN_ISSUER_SESSION joinSession,TSS_DAA_CRED_ISSUER * credIssuer)268 TSPICALL Tspi_DAA_IssueCredential_internal
269 (
270           TSS_HDAA  hDAA,     // in
271           UINT32    attributesIssuerLength,       // in
272           BYTE**    attributesIssuer,   // in
273           TSS_DAA_CREDENTIAL_REQUEST    credentialRequest,  // in
274           TSS_DAA_JOIN_ISSUER_SESSION   joinSession,        // in
275           TSS_DAA_CRED_ISSUER*          credIssuer          // out
276 ) {
277           TSS_RESULT result = TSS_SUCCESS;
278           TCS_CONTEXT_HANDLE tcsContext;
279           bi_ptr capitalU_hat_prime = NULL;
280           bi_ptr tmp1;
281           bi_ptr tmp2;
282           bi_ptr sa_i;
283           bi_ptr capitalU_prime = NULL;
284           bi_ptr c = NULL;
285           bi_ptr n = NULL;
286           bi_ptr sf0 = NULL;
287           bi_ptr sf1 = NULL;
288           bi_ptr sv_prime = NULL;
289           bi_ptr capitalR0 = NULL;
290           bi_ptr capitalR1 = NULL;
291           bi_ptr capitalS = NULL;
292           bi_ptr capitalU = NULL;
293           bi_ptr capitalU_hat = NULL;
294           bi_ptr capitalN_hat_i = NULL;
295           bi_ptr exp = NULL;
296           bi_ptr product_attr_receiver = NULL;
297           bi_ptr product_attr_issuer = NULL;
298           bi_ptr sv_tilde_prime = NULL;
299           bi_ptr capital_ni = NULL;
300           bi_ptr v_hat = NULL;
301           bi_ptr fraction_A = NULL;
302           bi_ptr capitalA = NULL;
303           bi_ptr e = NULL;
304           bi_ptr eInverse = NULL;
305           bi_ptr v_prime_prime = NULL;
306           bi_ptr c_prime = NULL;
307           bi_ptr s_e = NULL;
308           bi_ptr zeta = NULL;
309           TSS_DAA_PK *daa_pk_extern;
310           TSS_DAA_PK_internal *pk_intern;
311           TSS_DAA_PRIVATE_KEY *private_key;
312           UINT32 i, chLength, challengeLength, length, interval;
313           EVP_MD_CTX *mdctx;
314           BYTE *ch = NULL, *challenge = NULL;
315 
316           tmp1 = bi_new_ptr();
317           tmp2 = bi_new_ptr();
318           if( tmp1 == NULL || tmp2 == NULL) {
319                     LogError("malloc of BI <%s> failed", "tmp1, tmp2");
320                     result = TSPERR(TSS_E_OUTOFMEMORY);
321                     goto close;
322           }
323           if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS) goto close;
324           // 1 TODO Check the TPM rogue list
325 
326           // 2 verify the authentication proof of the TPM
327           result = verify_authentificity(&credentialRequest, &joinSession);
328           if( result != TSS_SUCCESS) goto close;
329           daa_pk_extern = (TSS_DAA_PK *)(((TSS_DAA_KEY_PAIR *)joinSession.issuerKeyPair)->public_key);
330           pk_intern = e_2_i_TSS_DAA_PK( daa_pk_extern);
331           n = bi_set_as_nbin( daa_pk_extern->modulusLength,
332                     daa_pk_extern->modulus); // allocation
333           if( n == NULL) {
334                     LogError("malloc of BI <%s> failed", "n");
335                     result = TSPERR(TSS_E_OUTOFMEMORY);
336                     goto close;
337           }
338           capitalR0 = bi_set_as_nbin( daa_pk_extern->capitalR0Length,
339                     daa_pk_extern->capitalR0); // allocation
340           if( capitalR0 == NULL) {
341                     LogError("malloc of BI <%s> failed", "capitalR0");
342                     result = TSPERR(TSS_E_OUTOFMEMORY);
343                     goto close;
344           }
345           capitalR1 = bi_set_as_nbin( daa_pk_extern->capitalR1Length,
346                     daa_pk_extern->capitalR1); // allocation
347           if( capitalR1 == NULL) {
348                     LogError("malloc of BI <%s> failed", "capitalR1");
349                     result = TSPERR(TSS_E_OUTOFMEMORY);
350                     goto close;
351           }
352           capitalS = bi_set_as_nbin( daa_pk_extern->capitalSLength,
353                     daa_pk_extern->capitalS); // allocation
354           if( capitalS == NULL) {
355                     LogError("malloc of BI <%s> failed", "capitalS");
356                     result = TSPERR(TSS_E_OUTOFMEMORY);
357                     goto close;
358           }
359           capitalU = bi_set_as_nbin( credentialRequest.capitalULength,
360                     credentialRequest.capitalU); // allocation
361           if( capitalU == NULL) {
362                     LogError("malloc of BI <%s> failed", "capitalU");
363                     result = TSPERR(TSS_E_OUTOFMEMORY);
364                     goto close;
365           }
366           sv_tilde_prime = bi_set_as_nbin( credentialRequest.sVtildePrimeLength,
367                     credentialRequest.sVtildePrime); // allocation
368           if( sv_tilde_prime == NULL) {
369                     LogError("malloc of BI <%s> failed", "sv_tilde_prime");
370                     result = TSPERR(TSS_E_OUTOFMEMORY);
371                     goto close;
372           }
373           capital_ni = bi_set_as_nbin( credentialRequest.capitalNiLength,
374                     credentialRequest.capitalNi); // allocation
375           if( capital_ni == NULL) {
376                     LogError("malloc of BI <%s> failed", "capital_ni");
377                     result = TSPERR(TSS_E_OUTOFMEMORY);
378                     goto close;
379           }
380           // 3 Verify the correctness proof of the credential request
381           // 3.a TODO commitments
382 
383           // 3.b
384           capitalU_prime = bi_set_as_nbin( joinSession.capitalUprimeLength,
385                     joinSession.capitalUprime); // allocation
386           if( capitalU_prime == NULL) {
387                     LogError("malloc of BI <%s> failed", "capitalU_prime");
388                     result = TSPERR(TSS_E_OUTOFMEMORY);
389                     goto close;
390           }
391           sf0 = bi_set_as_nbin( credentialRequest.sF0Length,
392                     credentialRequest.sF0); // allocation
393           if( sf0 == NULL) {
394                     LogError("malloc of BI <%s> failed", "sf0");
395                     result = TSPERR(TSS_E_OUTOFMEMORY);
396                     goto close;
397           }
398           sf1 = bi_set_as_nbin( credentialRequest.sF1Length,
399                     credentialRequest.sF1); // allocation
400           if( sf1 == NULL) {
401                     LogError("malloc of BI <%s> failed", "sf1");
402                     result = TSPERR(TSS_E_OUTOFMEMORY);
403                     goto close;
404           }
405           sv_prime = bi_set_as_nbin( credentialRequest.sVprimeLength,
406                     credentialRequest.sVprime); // allocation
407           if( sv_prime == NULL) {
408                     LogError("malloc of BI <%s> failed", "sv_prime");
409                     result = TSPERR(TSS_E_OUTOFMEMORY);
410                     goto close;
411           }
412           c = bi_set_as_nbin( credentialRequest.challengeLength,
413                     credentialRequest.challenge); // allocation
414           if( c == NULL) {
415                     LogError("malloc of BI <%s> failed", "c");
416                     result = TSPERR(TSS_E_OUTOFMEMORY);
417                     goto close;
418           }
419           capitalU_hat_prime = bi_new_ptr();// allocation
420           if( capitalU_hat_prime == NULL) {
421                     LogError("malloc of BI <%s> failed", "c");
422                     result = TSPERR(TSS_E_OUTOFMEMORY);
423                     goto close;
424           }
425           // capitalU_hat_prime = capitalU_prime ~% n
426           bi_invert_mod( capitalU_hat_prime, capitalU_prime, n);
427           // capitalU_hat_prime = ( capitalU_hat_prime ^ c ) % n
428           bi_mod_exp( capitalU_hat_prime, capitalU_hat_prime, c, n);
429           // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalR0 ^ sf0)) % n
430           bi_mod_exp( tmp1, capitalR0, sf0, n);
431           bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1);
432           bi_mod( capitalU_hat_prime, capitalU_hat_prime, n);
433           // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalR1 ^ sf1)) % n
434           bi_mod_exp( tmp1, capitalR1, sf1, n);
435           bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1);
436           bi_mod( capitalU_hat_prime, capitalU_hat_prime, n);
437           // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalS ^ sv_prime)) % n
438           bi_mod_exp( tmp1, capitalS, sv_prime, n);
439           bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1);
440           bi_mod( capitalU_hat_prime, capitalU_hat_prime, n);
441           // verify blinded encoded attributes of the Receiver
442           product_attr_receiver = bi_new_ptr();
443           bi_set( product_attr_receiver, bi_1);
444           length = ( DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8;
445           for( i=0; i<credentialRequest.sALength; i++) {
446                     sa_i = bi_set_as_nbin( length, credentialRequest.sA[i]); // allocation
447                     if( sa_i == NULL) {
448                               LogError("malloc of BI <%s> failed", "sa_i");
449                               result = TSPERR(TSS_E_OUTOFMEMORY);
450                               goto close;
451                     }
452                     bi_mod_exp( tmp1, pk_intern->capitalRReceiver->array[i], sa_i, n);
453                     bi_mul( product_attr_receiver, product_attr_receiver, tmp1);
454                     bi_mod( product_attr_receiver, product_attr_receiver, n);
455                     bi_free_ptr( sa_i);
456           }
457           // tmp1 = ( 1 / capitalU ) % n
458           bi_invert_mod( tmp1, capitalU, n);
459           capitalU_hat = bi_new_ptr();
460           if( capitalU_hat == NULL) {
461                     LogError("malloc of BI <%s> failed", "capitalU_hat");
462                     result = TSPERR(TSS_E_OUTOFMEMORY);
463                     goto close;
464           }
465           bi_mul( capitalU_hat, capitalU_prime, tmp1);
466           // capitalU_hat = capitalU_prime / capitalU
467           bi_mod( capitalU_hat, capitalU_hat, n);
468           // capital_Uhat = ( (capital_Uhat ^ c ) % n
469           bi_mod_exp( capitalU_hat, capitalU_hat, c, n);
470           // capital_Uhat = ( capital_Uhat * ( capitalS ^ sv_tilde_prime) % n ) % n
471           bi_mod_exp( tmp1, pk_intern->capitalS, sv_tilde_prime, n);
472           bi_mul( capitalU_hat, capitalU_hat, tmp1);
473           bi_mod( capitalU_hat, capitalU_hat, n);
474           bi_mul( capitalU_hat, capitalU_hat, product_attr_receiver);
475           bi_mod( capitalU_hat, capitalU_hat, n);
476           // capital_Nhat_i = (( capital_Ni ~% pk_intern->capitalGamma ) ^ c ) % pk_intern->capitalGamma
477           capitalN_hat_i = bi_new_ptr();
478           bi_invert_mod( capitalN_hat_i, capital_ni, pk_intern->capitalGamma);
479           bi_mod_exp( capitalN_hat_i, capitalN_hat_i, c, pk_intern->capitalGamma);
480           // exp = sf1 << (DAA_PARAM_SIZE_F_I) + sf0
481           exp = bi_new_ptr();
482           if( exp == NULL) {
483                     LogError("malloc of BI <%s> failed", "exp");
484                     result = TSPERR(TSS_E_OUTOFMEMORY);
485                     goto close;
486           }
487           bi_shift_left( exp, sf1, DAA_PARAM_SIZE_F_I);
488           bi_add( exp, exp, sf0);
489           zeta = compute_zeta( pk_intern->issuerBaseNameLength,
490                                                   pk_intern->issuerBaseName,
491                                                   pk_intern);
492           // capital_Nhat_i = ( capital_Nhat_i *
493           //                            ( ( issuer.zeta ^ exp) % pk->capitalGamma) ) % pk->capitalGamma
494           bi_mod_exp( tmp1, zeta, exp, pk_intern->capitalGamma);
495           bi_mul( capitalN_hat_i, capitalN_hat_i, tmp1);
496           bi_mod( capitalN_hat_i, capitalN_hat_i, pk_intern->capitalGamma);
497 
498           LogDebug("calculation Uhat:                capitalS:%s\n", bi_2_hex_char( pk_intern->capitalS));
499           LogDebug("calculation Uhat:       sv_tilde_prime:%s\n", bi_2_hex_char( sv_tilde_prime));
500           LogDebug("calculation Uhat:                          n:%s\n", bi_2_hex_char( n));
501           LogDebug("calculation Uhat: product_attributes:%s\n", bi_2_hex_char( product_attr_receiver));
502           LogDebug("calculation NhatI:                     zeta:%s\n", bi_2_hex_char( zeta));
503           LogDebug("calculation NhatI:                      exp:%s\n", bi_2_hex_char( exp));
504           LogDebug("calculation NhatI:      capitalGamma:%s\n", bi_2_hex_char( pk_intern->capitalGamma));
505           // calculate challenge
506           result = compute_join_challenge_host(hDAA,
507                                                                       pk_intern,
508                                                                       capitalU,
509                                                                       capitalU_prime,
510                                                                       capitalU_hat,
511                                                                       capitalU_hat_prime,
512                                                                       capital_ni,
513                                                                       capitalN_hat_i,
514                                                                       0, // TODO: commitmentsProofLength
515                                                                       NULL, // TODO: commits
516                                                                       joinSession.nonceIssuerLength,
517                                                                       joinSession.nonceIssuer,
518                                                                       &chLength,          // out
519                                                                       &ch);               // out allocation
520           if( result != TSS_SUCCESS) goto close;
521           LogDebug("JoinChallengeHost: %s", dump_byte_array( chLength, ch));
522           mdctx = EVP_MD_CTX_create();
523           EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
524           EVP_DigestUpdate(mdctx,  ch, chLength);
525           challengeLength = EVP_MD_CTX_size(mdctx);
526           challenge = (BYTE *)malloc( challengeLength);
527           if( challenge == NULL) {
528                     LogError("malloc of %d bytes failed", challengeLength);
529                     result = TSPERR(TSS_E_OUTOFMEMORY);
530                     goto close;
531           }
532           EVP_DigestUpdate(mdctx,  credentialRequest.nonceTpm, credentialRequest.nonceTpmLength);
533           EVP_DigestFinal(mdctx, challenge, NULL);
534           // checks
535           if( credentialRequest.challengeLength != challengeLength ||
536                     memcmp( credentialRequest.challenge, challenge, challengeLength)!=0) {
537                     LogError("Verification of c failed - Step 3.f.i");
538                     LogError("credentialRequest.challenge[%d]=%s",
539                               credentialRequest.challengeLength,
540                               dump_byte_array( credentialRequest.challengeLength,
541                                         credentialRequest.challenge));
542                     LogError("challenge[%d]=%s",
543                               challengeLength,
544                               dump_byte_array( challengeLength, challenge));
545                     result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
546                     goto close;
547           }
548           // + 1 because the result of ( rA(43 bits)  + c(20 bits) * a(13 bits)) can
549           // shift 1 bit above the normal size (43 bits)
550           length = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 1;
551           if( bi_length( sf0) > (long)length) {
552                     LogError( "Verification of sF0 failed - Step 3.f.ii");
553                     LogError("\tsf0 bits length: %d  expected maximum length:%d\n",
554                                         (int)bi_length( sf0), (int)length);
555                     result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
556                     goto close;
557           }
558           if( bi_length( sf1) > (long)length) {
559                     LogError( "Verification of sF1 failed - Step 3.f.ii");
560                     LogError("\tsf1 length: %d  expected maximum length:%d\n",
561                                         (int)bi_length( sf1), (int)length);
562                     result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
563                     goto close;
564           }
565           // blinded attributes
566           length = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES;
567           for( i=0; i<credentialRequest.sALength; i++) {
568                     sa_i = bi_set_as_nbin( ( length + 7) / 8, credentialRequest.sA[i]); // allocation
569                     if( sa_i == NULL) {
570                               LogError("malloc of BI <%s> failed", "sa_i");
571                               result = TSPERR(TSS_E_OUTOFMEMORY);
572                               goto close;
573                     }
574                     if( bi_length( sa_i) > (long)length) {
575                               LogError("Verification of sA[%d] failed - Step 3.f.ii", i);
576                               LogError("sA.length=%d length=%d", (int)bi_length( sa_i), length);
577                               result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
578                               goto close;
579                     }
580                     bi_free_ptr( sa_i);
581                     if( result != TSS_SUCCESS) goto close;
582           }
583           length = DAA_PARAM_SIZE_RSA_MODULUS + 2 * DAA_PARAM_SAFETY_MARGIN +
584                               DAA_PARAM_SIZE_MESSAGE_DIGEST;
585           if( bi_length( sv_prime) > (int)length) {
586                     LogError("Verification of sVprime failed - Step 3.f.iii\n");
587                     LogError("\tsv_prime bits length: %d  expected maximum length:%d\n",
588                                         (int)bi_length( sv_prime), (int)length);
589                     result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
590                     goto close;
591           }
592           if( bi_nbin_size( sv_tilde_prime) > (int)length) {
593                     LogError("Verification of sVtildePrime failed - Step 3.f.iii");
594                     LogError("\tsv_tilde_prime bits length: %d  expected maximum length:%d\n",
595                                         (int)bi_length( sv_tilde_prime), (int)length);
596                     result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
597                     goto close;
598           }
599           // compute credential
600           v_hat = bi_new_ptr();
601           if( v_hat == NULL) {
602                     LogError("malloc of BI <%s> failed", "v_hat");
603                     result = TSPERR(TSS_E_OUTOFMEMORY);
604                     goto close;
605           }
606           bi_urandom( v_hat, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE - 1);
607           length = DAA_PARAM_SIZE_EXPONENT_CERTIFICATE;
608           interval = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE;
609           e = bi_new_ptr();
610           if( e == NULL) {
611                     LogError("malloc of BI <%s> failed", "e");
612                     result = TSPERR(TSS_E_OUTOFMEMORY);
613                     goto close;
614           }
615           compute_prime( e, length, interval);
616 
617           // v'' = ( 1 << DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE) + v_hat
618           v_prime_prime = bi_new_ptr();
619           bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE - 1);
620           bi_add( v_prime_prime, tmp1, v_hat);
621 
622           // fraction_A = (( pk->capitalS ^ v``) % n) * capitalU
623           fraction_A = bi_new_ptr();
624           if( fraction_A == NULL) {
625                     LogError("malloc of BI <%s> failed", "fraction_A");
626                     result = TSPERR(TSS_E_OUTOFMEMORY);
627                     goto close;
628           }
629           bi_mod_exp( fraction_A, pk_intern->capitalS, v_prime_prime, n);
630           bi_mul( fraction_A, fraction_A, capitalU);
631           bi_mod( fraction_A, fraction_A, n);
632 
633           // encode attributes
634           bi_free_ptr( tmp1);
635           product_attr_issuer = bi_new_ptr();
636           if( product_attr_issuer == NULL) {
637                     LogError("malloc of BI <%s> failed", "product_attr_issuer");
638                     result = TSPERR(TSS_E_OUTOFMEMORY);
639                     goto close;
640           }
641           bi_set( product_attr_issuer, bi_1);
642           for( i=0; i< attributesIssuerLength; i++) {
643                     tmp1 = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, attributesIssuer[i]); // allocation
644                     bi_mod_exp( tmp2, pk_intern->capitalRIssuer->array[i], tmp1, n);
645                     bi_mul( product_attr_issuer, product_attr_issuer, tmp2);
646                     bi_mod( product_attr_issuer, product_attr_issuer, n);
647                     bi_free_ptr( tmp1);
648           }
649           tmp1 = bi_new_ptr();
650           if( tmp1 == NULL) {
651                     LogError("malloc of BI <%s> failed", "tmp1");
652                     result = TSPERR(TSS_E_OUTOFMEMORY);
653                     goto close;
654           }
655           bi_mul( fraction_A, fraction_A, product_attr_issuer);
656           bi_mod( fraction_A, fraction_A, n);
657 
658           bi_invert_mod( fraction_A, fraction_A, n);
659           bi_mul( fraction_A, fraction_A, pk_intern->capitalZ);
660           bi_mod( fraction_A, fraction_A, n);
661 
662           private_key = (TSS_DAA_PRIVATE_KEY *)
663                                         (((TSS_DAA_KEY_PAIR *)joinSession.issuerKeyPair)->private_key);
664           bi_free_ptr( tmp2);
665           tmp2 = bi_set_as_nbin( private_key->productPQprimeLength,
666                     private_key->productPQprime); // allocation
667           if( tmp2 == NULL) {
668                     LogError("malloc of BI <%s> failed", "tmp2");
669                     result = TSPERR(TSS_E_OUTOFMEMORY);
670                     goto close;
671           }
672           eInverse = bi_new_ptr();
673           if( eInverse == NULL) {
674                     LogError("malloc of BI <%s> failed", "eInverse");
675                     result = TSPERR(TSS_E_OUTOFMEMORY);
676                     goto close;
677           }
678           bi_invert_mod( eInverse, e, tmp2);
679           capitalA = bi_new_ptr();
680           if( capitalA == NULL) {
681                     LogError("malloc of BI <%s> failed", "capitalA");
682                     result = TSPERR(TSS_E_OUTOFMEMORY);
683                     goto close;
684           }
685           LogDebug("fraction_A[%ld]=%s", bi_nbin_size( fraction_A), bi_2_hex_char( fraction_A));
686           LogDebug("eInverse[%ld]=%s", bi_nbin_size( eInverse), bi_2_hex_char( eInverse));
687           LogDebug("productPQprime[%ld]=%s", bi_nbin_size( tmp2), bi_2_hex_char( tmp2));
688           LogDebug("eInverse[%ld]=%s", bi_nbin_size( eInverse), bi_2_hex_char( eInverse));
689           LogDebug("e[%ld]=%s", bi_nbin_size( e), bi_2_hex_char( e));
690           LogDebug("n[%ld]=%s", bi_nbin_size( n), bi_2_hex_char( n));
691           bi_mod_exp( capitalA, fraction_A, eInverse, n);
692 
693           compute_credential_proof( pk_intern,
694                                         capitalA,
695                                         fraction_A,
696                                         eInverse,
697                                         v_prime_prime,
698                                         tmp2, // productPQprime
699                                         credentialRequest.noncePlatformLength,
700                                         credentialRequest.noncePlatform,
701                                         &c_prime, // out: allocation
702                                         &s_e);    // out: allocation
703           // populate credIssuer (TSS_DAA_CRED_ISSUER *)
704           credIssuer->capitalA = calloc_tspi( tcsContext, bi_nbin_size( capitalA));
705           if( credIssuer->capitalA == NULL) {
706                     LogError("malloc of %ld bytes failed", bi_nbin_size( capitalA));
707                     result = TSPERR(TSS_E_OUTOFMEMORY);
708                     goto close;
709           }
710           bi_2_nbin1( &(credIssuer->capitalALength), credIssuer->capitalA, capitalA);
711           credIssuer->e = calloc_tspi( tcsContext, bi_nbin_size( e));
712           if( credIssuer->e == NULL) {
713                     LogError("malloc of %ld bytes failed", bi_nbin_size( e));
714                     result = TSPERR(TSS_E_OUTOFMEMORY);
715                     goto close;
716           }
717           bi_2_nbin1( &(credIssuer->eLength), credIssuer->e, e);
718           credIssuer->vPrimePrime = calloc_tspi( tcsContext, bi_nbin_size( v_prime_prime));
719           if( credIssuer->vPrimePrime == NULL) {
720                     LogError("malloc of %ld bytes failed", bi_nbin_size( v_prime_prime));
721                     result = TSPERR(TSS_E_OUTOFMEMORY);
722                     goto close;
723           }
724           bi_2_nbin1( &(credIssuer->vPrimePrimeLength), credIssuer->vPrimePrime, v_prime_prime);
725           // attributes issuer
726           credIssuer->attributesIssuerLength = attributesIssuerLength;
727           credIssuer->attributesIssuer = calloc_tspi( tcsContext,
728                                                             attributesIssuerLength * sizeof( BYTE *));
729           if( credIssuer->attributesIssuer == NULL) {
730                     LogError("malloc of %d bytes failed", attributesIssuerLength * sizeof( BYTE *));
731                     result = TSPERR(TSS_E_OUTOFMEMORY);
732                     goto close;
733           }
734           for( i=0; i< attributesIssuerLength; i++) {
735                     credIssuer->attributesIssuer[i] = calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8);
736                     if( credIssuer->attributesIssuer[i] == NULL) {
737                               LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
738                               result = TSPERR(TSS_E_OUTOFMEMORY);
739                               goto close;
740                     }
741                     memcpy( credIssuer->attributesIssuer[i], attributesIssuer[i], DAA_PARAM_SIZE_F_I / 8);
742           }
743           credIssuer->cPrime = calloc_tspi( tcsContext, bi_nbin_size( c_prime));
744           if( credIssuer->cPrime == NULL) {
745                     LogError("malloc of %ld bytes failed", bi_nbin_size( c_prime));
746                     result = TSPERR(TSS_E_OUTOFMEMORY);
747                     goto close;
748           }
749           bi_2_nbin1( &(credIssuer->cPrimeLength), credIssuer->cPrime, c_prime);
750           credIssuer->sE = calloc_tspi( tcsContext, bi_nbin_size( s_e));
751           if( credIssuer->sE == NULL) {
752                     LogError("malloc of %ld bytes failed", bi_nbin_size( s_e));
753                     result = TSPERR(TSS_E_OUTOFMEMORY);
754                     goto close;
755           }
756           bi_2_nbin1( &(credIssuer->sELength), credIssuer->sE, s_e);
757 
758 close:
759           EVP_MD_CTX_destroy(mdctx);
760           //free_TSS_DAA_PK( daa_pk_extern);
761           if( ch != NULL) free( ch);
762           if( challenge != NULL) free( challenge);
763           FREE_BI( tmp1);
764           FREE_BI( tmp2);
765           FREE_BI( s_e);
766           FREE_BI( c_prime);
767           FREE_BI( capitalA);
768           FREE_BI( v_prime_prime);
769           FREE_BI( eInverse);
770           FREE_BI( e);
771           FREE_BI( fraction_A);
772           FREE_BI( v_hat);
773           FREE_BI( capital_ni);
774           FREE_BI( sv_tilde_prime);
775           FREE_BI( product_attr_receiver);
776           FREE_BI( product_attr_issuer);
777           FREE_BI( capitalU_hat_prime);
778           FREE_BI( capitalU_prime);
779           FREE_BI( sv_prime);
780           FREE_BI( exp);
781           FREE_BI( capitalN_hat_i);
782           FREE_BI( capitalU_hat);
783           FREE_BI( capitalU);
784           FREE_BI( capitalS);
785           FREE_BI( capitalR1);
786           FREE_BI( capitalR0);
787           FREE_BI( sf1);
788           FREE_BI( sf0);
789           FREE_BI( n);
790           FREE_BI( c);
791           FREE_BI( zeta);
792           return result;
793 }
794