xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/daa/daa_issuer/issue_credential.c (revision 1023804e3833a0bd94414f2545512128f6502c74)
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