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