xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/daa/daa_platform/test_join.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 #include <stdlib.h>
12 #include <string.h>
13 #include <errno.h>
14 
15 #include "daa_structs.h"
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "spi_internal_types.h"
19 #include "spi_utils.h"
20 #include "obj.h"
21 #include "tsplog.h"
22 #include "daa_parameter.h"
23 #include "verifier.h"
24 #include "platform.h"
25 
26 // for RSA Key
27 #include <openssl/rsa.h>
28 
29 #define DEFAULT_FILENAME "issuer.txt"
30 #define DEFAULT_CREDENTIAL_FILENAME "credential.txt"
31 #define DEFAULT_DAACOUNTER 0x01020304
32 #define DEFAULT_OWN_PASSWD "OWN_PWD"
33 
34 // from IssuerFactory
35 static const int DEFAULT_KEY_CHAIN_LENGTH = 3;
36 
37 typedef struct tdIssuer {
38 	// use on Tspi calls
39 	TSS_DAA_PK *pk_extern;
40 	TSS_DAA_KEY_PAIR *key_pair_extern;
41 
42 	// used internally
43 	int length_key_chain;
44 	RSA **key_chain;
45 	TSS_DAA_PK_internal *pk;
46 	DAA_PRIVATE_KEY_internal *private_key;
47 	TSS_DAA_PK_PROOF_internal *pk_proof;
48 	//RSA **auth_key_pairs;
49 	BYTE **pk_signatures;
50 	bi_ptr zeta;
51 } Issuer;
52 
alloc(UINT32 length,TCS_CONTEXT_HANDLE tcsContext)53 void *alloc( UINT32 length, TCS_CONTEXT_HANDLE tcsContext) {
54 	void *result = calloc_tspi( tcsContext, length);
55 	LogDebug("allocate tspi memory:%d", (int)result);
56 	return result;
57 }
58 
59 /**
60 Used by RSA_generate_key
61 From RSA_generate_key documentation:
62 -> callback(2, n, cb_arg) is called when n-th randomly generated prime is rejected
63 -> callback(3, 0, cb_arg) is called when p is found with p-1 more or less prime to e
64 -> callback(3, 1, cb_arg) repeatedly called for prime q
65 */
callback(int step,int number,void * arg)66 void callback(int step, int number, void *arg) {
67 #ifdef DAA_DEBUG
68 	putc( '.', stdout); fflush( stdout);
69 #endif
70 }
71 
sign(BYTE * buffer_2_sign,int len_buffer_2_sign,RSA * rsa,BYTE * signature,int * len_signature)72 int sign( BYTE *buffer_2_sign,
73 	int len_buffer_2_sign,
74 	RSA *rsa,
75 	BYTE *signature,
76 	int *len_signature
77 ) {
78 	EVP_MD_CTX *ctx;
79 	int len_message = EVP_MD_size( EVP_sha1()), current_len_message;
80 	BYTE *message = (BYTE *)malloc( len_message);
81 	int ret;
82 
83 	ctx = EVP_MD_CTX_create();
84 	EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
85 	EVP_DigestUpdate(ctx, buffer_2_sign, len_buffer_2_sign);
86 	EVP_DigestFinal_ex(ctx, message, &current_len_message);
87 	LogDebug("Sign rsa-> with message (length=%d)", current_len_message);
88 //	int RSA_sign(int type, unsigned char *m, unsigned int m_len,
89 //		     unsigned char *sigret, unsigned int *siglen, RSA *rsa);
90 	ret = RSA_sign( NID_sha1, message, current_len_message, signature, len_signature, rsa);
91 	if( ret == 0) {
92 		LogError("Error in RSA_sign: %s", ERR_error_string( ERR_get_error(), NULL));
93 	}
94 	LogDebug("Sign rsa-> signature (length=%d)", *len_signature );
95 	EVP_MD_CTX_destroy(ctx);
96 	free( message);
97 	return ret;
98 }
99 
100 /* Compute key chain. */
init_key_chain(int length_key_chain,Issuer * issuer)101 static int init_key_chain(int length_key_chain, Issuer *issuer) {
102 	BYTE *signature;
103 	int i, len_sign, ret;
104 	BYTE *modulus;
105 	BYTE *message;
106 	// generate RSA key of length  DAA_PARAM_KEY_SIZE with exponent
107 	// 65537 (java.security.spec.RSAKeyGenParameterSpec.F4)
108 	unsigned long e = 65537;
109 	RSA *rsa;
110 	bi_ptr bi;
111 	EVP_MD_CTX *ctx;
112 	int len_message = EVP_MD_size( EVP_sha1());
113 	int current_len_message;
114 
115 	EVP_MD_CTX_create(ctx);
116 	message = (BYTE *)malloc(len_message);
117 	if( length_key_chain < 1) {
118 		free( message);
119 		return -1;
120 	}
121 	issuer->length_key_chain = length_key_chain;
122 	issuer->key_chain = (RSA **)malloc(sizeof(RSA *) * length_key_chain);
123 	issuer->pk_signatures = (BYTE **)malloc(sizeof(BYTE *) * length_key_chain);
124 	for(i = 0; i<length_key_chain; i++) {
125 		rsa = RSA_generate_key( DAA_PARAM_KEY_SIZE, e, &callback, NULL);
126 		if( (BN_num_bits(rsa->n) + 7) / 8 != (DAA_PARAM_KEY_SIZE + 7) / 8) {
127 			LogError("BN_num_bits(rsa->n) + 7) / 8 != (DAA_PARAM_KEY_SIZE + 7) / 8)");
128 			return -1;
129 		}
130 		issuer->key_chain[i] = rsa;
131 		if( i > 0) {
132 			signature = (BYTE *)malloc( RSA_size(rsa));
133 			modulus = (BYTE *)malloc( DAA_PARAM_KEY_SIZE / 8);
134 			// signature algorithm from Issuer.java -  "SHA1withRSA"
135 			// sign the modulus (n) of the RSA key with the previous RSA key (chain)
136 			// 	sign rsa(i)->n with auth_key_pairs[i-1]
137 			LogDebug("modulus=%s\n", dump_byte_array(256, modulus));
138 			LogDebug("signature=%s\n", dump_byte_array(256, signature));
139 			bi = bi_new_ptr();
140 			bi_set_as_hex( bi, BN_bn2hex( rsa->n));
141 			bi_2_byte_array( modulus, DAA_PARAM_KEY_SIZE / 8, bi);
142 			LogDebug("bi=%s", bi_2_hex_char( bi));
143 			bi_free_ptr(  bi);
144 			EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
145 			EVP_DigestUpdate(ctx, modulus, DAA_PARAM_KEY_SIZE / 8);
146 			EVP_DigestFinal_ex(ctx, message, &current_len_message);
147 			ret = RSA_sign( NID_sha1, message, current_len_message,
148 					signature, &len_sign, issuer->key_chain[i-1]);
149 			if( ret == 0) {
150 				LogError("Error in RSA_sign: %s",
151 					ERR_error_string( ERR_get_error(), NULL));
152 			}
153 			LogDebug("Sign rsa->n (length=%d) with signature (length=%d,\
154  truelength=%d message_len=%d) ret = %d ERROR?=%s",
155 				RSA_size(rsa),
156 				DAA_PARAM_KEY_SIZE / 8,
157 				len_sign,
158 				current_len_message,
159 				ret,
160 				ERR_error_string( ERR_get_error(),
161 				NULL) );
162 			LogDebug("message=%s\n", dump_byte_array(256, message));
163 			LogDebug("signature=%s\n",dump_byte_array(256, signature));
164 			issuer->pk_signatures[i-1] = signature;
165 		}
166 	}
167 	free( message);
168 	EVP_MD_CTX_destroy(ctx);
169 	return 0;
170 }
171 
initIssuer(int length_key_chain,char * filename,char * exec,TSS_HCONTEXT hContext)172 Issuer* initIssuer(int length_key_chain, char *filename, char *exec, TSS_HCONTEXT hContext) {
173 	FILE *file;
174 	EVP_MD_CTX *mdctx;
175 	Issuer *issuer = (Issuer *)malloc(sizeof( Issuer));
176 	TPM_DAA_ISSUER *tpm_daa_issuer;
177 	bi_ptr modulus_N0;
178 	int len_issuer_settings, len_signature;
179 	BYTE *modulus_N0_bytes;
180 	BYTE *digest_n0;
181 	BYTE *issuer_settings_byte_array;
182 	BYTE *sign_data;
183 	BYTE *signature;
184 	RSA *private_nn;
185 	KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof;
186 
187 	LogDebug("Loading issuer info (keypair & proof) -> \'%s\'", filename);
188 	file = fopen( filename, "r");
189 	if( file == NULL) {
190 		fprintf( stderr, "%s: Error when opening \'%s\': %s\n",
191 			exec,
192 			filename,
193 			strerror( errno));
194 		free( issuer);
195 		return NULL;
196 	}
197 	key_pair_with_proof = load_KEY_PAIR_WITH_PROOF( file);
198 	if( key_pair_with_proof == NULL) {
199 		LogError( "Error when reading \'%s\': %s\n", filename, strerror( errno));
200 		free( issuer);
201 		return NULL;
202 	}
203 	fclose( file);
204 	issuer->pk = key_pair_with_proof->pk;
205 	issuer->pk_extern = i_2_e_TSS_DAA_PK( issuer->pk, &alloc, hContext);
206 	issuer->key_pair_extern = (TSS_DAA_KEY_PAIR *)malloc( sizeof(TSS_DAA_KEY_PAIR));
207 	init_tss_version( issuer->key_pair_extern);
208 	issuer->key_pair_extern->public_key = issuer->pk_extern;
209 	issuer->key_pair_extern->private_key = i_2_e_TSS_DAA_PRIVATE_KEY(
210 		key_pair_with_proof->private_key,
211 		&alloc, hContext);
212 	issuer->pk_proof = key_pair_with_proof->proof;
213 	issuer->private_key = key_pair_with_proof->private_key;
214 	init_key_chain( length_key_chain, issuer);
215 	issuer->zeta = compute_zeta( issuer->pk->issuerBaseNameLength,
216 					issuer->pk->issuerBaseName, issuer->pk);
217 	// sign "issuer settings"
218 	modulus_N0 = bi_new_ptr();
219 	bi_set_as_hex( modulus_N0, BN_bn2hex( issuer->key_chain[0]->n));
220 	// in TPM, N0 is hashed by hashing the scratch (256 bytes) so it must
221 	// be formatted according to the scratch size (TPM_DAA_SIZE_issuerModulus)
222 	modulus_N0_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus);
223 	bi_2_byte_array( modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus, modulus_N0);
224 	bi_free_ptr( modulus_N0);
225 
226 	if( TPM_DAA_SIZE_issuerModulus * 8 != DAA_PARAM_KEY_SIZE) {
227 		LogError("TPM_DAA_SIZE_issuerModulus * 8 (%d) != DAA_PARAM_KEY_SIZE(%d)",
228 			TPM_DAA_SIZE_issuerModulus*8,
229 			DAA_PARAM_KEY_SIZE);
230 		free( issuer);
231 		return NULL;
232 	}
233 
234 	EVP_MD_CTX_create(mdctx);
235 	EVP_DigestInit_ex(mdctx, DAA_PARAM_get_message_digest(), NULL);
236 	// digestN0 = hash( modulus_N0)
237 	EVP_DigestUpdate(mdctx,  modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus);
238 	digest_n0 = (BYTE *)EVP_MD_CTX_create();
239 	EVP_DigestFinal_ex(mdctx, digest_n0, NULL);
240 	tpm_daa_issuer = convert2issuer_settings( issuer->pk);
241 	issuer_settings_byte_array = issuer_2_byte_array( tpm_daa_issuer, &len_issuer_settings);
242 	// data to sign: concatenation of digest_n0 and issuer_settings_byte_array
243 	sign_data = (BYTE *)malloc( EVP_MD_CTX_size(mdctx) + len_issuer_settings);
244 	memcpy( sign_data, digest_n0, EVP_MD_CTX_size(mdctx));
245 	memcpy( &sign_data[EVP_MD_CTX_size(mdctx)],
246 			issuer_settings_byte_array,
247 			len_issuer_settings);
248 	free( issuer_settings_byte_array);
249 	// sign digest of TPM compatible Issuer key (sign_data)
250 	private_nn = issuer->key_chain[issuer->length_key_chain - 1];
251 	signature = (BYTE *)malloc( RSA_size(private_nn));
252 	if ( sign( sign_data, EVP_MD_CTX_size(mdctx) + len_issuer_settings,
253 			private_nn,
254 			signature,
255 			&len_signature) ==0) {
256 		LogError("Can not sign digest of TPM compatible Issuer key");
257 		goto close;
258 	}
259 	issuer->pk_signatures[ issuer->length_key_chain - 1] = signature;
260 	LogDebug("Set last signature sign[%d] = %s",
261 			issuer->length_key_chain - 1,
262 			dump_byte_array(EVP_MD_size( EVP_sha1()),
263 			signature));
264 	// TODO sign the complete public key of TPM compatible Issuer key
265 /*	EVP_DigestInit_ex(mdctx, DAA_PARAM_get_message_digest(), NULL);
266 	EVP_DigestUpdate(mdctx, digest_n0, EVP_MD_CTX_size(mdctx));
267 	pk_encoded = encoded_DAA_PK_internal( &pk_encodedLength, issuer->pk);
268 	EVP_DigestUpdate(mdctx,  pk_encoded, pk_encodedLength);
269 	EVP_DigestFinal(mdctx, , NULL);
270 	signature = (BYTE *)malloc( EVP_MD_size( EVP_sha1()));
271 	if (sign( sign_data, EVP_MD_CTX_size(mdctx) + len_issuer_settings,
272 		private_nn, signature, &len_signature) !=0) goto close;
273 */
274 close:
275 	EVP_MD_CTX_destroy(mdctx);
276 	free( digest_n0);
277 	free( sign_data);
278 	return issuer;
279 }
280 
print_usage(char * exec)281 int print_usage(char  *exec) {
282 	fprintf(stderr, "usage: %s\n", exec);
283 	fprintf(stderr, "\t-if,\t--issuer_file\n\t\tthe file that will contain all key\
284 pair and proof to be used by the issuer\n\t\t (default: %s)\n",
285 		DEFAULT_FILENAME);
286 	fprintf(stderr, "\t-dc,\t--daa_counter\n\t\tdaa counter (default: %d)\n",
287 		DEFAULT_DAACOUNTER);
288 	fprintf(stderr,
289 		"\t-pw,\t--passwd\n\t\ttpm owner password (default: %s)\n",
290 		DEFAULT_OWN_PASSWD);
291 	return -1;
292 }
293 
main(int argc,char * argv[])294 int main(int argc, char *argv[]) {
295 	TSS_HCONTEXT hContext;
296 	TSS_RESULT result;
297 	TSS_HTPM hTPM;
298 	TSS_HPOLICY hPolicy;
299 	int i, length;
300 	char *param, *filename = DEFAULT_FILENAME;
301 	char *credential_filename = DEFAULT_CREDENTIAL_FILENAME;
302 	UINT32 daaCounter = DEFAULT_DAACOUNTER;
303 	UINT32 capital_UPrimeLength;
304 	BYTE *capitalUPrime;
305 	TSS_DAA_IDENTITY_PROOF identityProof;
306 	TSS_DAA_JOIN_SESSION joinSession;
307 	TSS_DAA_JOIN_ISSUER_SESSION join_issuer_session;
308 	TSS_DAA_CREDENTIAL_REQUEST credentialRequest;
309 	TSS_DAA_CRED_ISSUER credIssuer;
310 	TSS_HDAA hDAA;
311 	Issuer* issuer;
312 	char *szTpmPasswd = DEFAULT_OWN_PASSWD;
313 	UINT32 endorsementKeyLength;
314 	BYTE *endorsementKey;
315 	UINT32 nonceIssuerLength;
316 	BYTE *nonceIssuer;
317 	UINT32 authenticationChallengeLength;
318 	BYTE *authenticationChallenge;
319 	bi_array_ptr capital_receiver;
320 	BYTE **attributesPlatform;
321 	UINT32 attributesPlatformLength;
322 	BYTE **attributesIssuer;
323 	UINT32 attributesIssuerLength;
324 	bi_t random;
325 	FILE *file;
326 
327 	init_tss_version( &identityProof);
328 	init_tss_version( &joinSession);
329 	init_tss_version( &join_issuer_session);
330 	init_tss_version( &credentialRequest);
331 	init_tss_version( &credIssuer);
332 	i = 1;
333 	while( i < argc) {
334 		param = argv[ i];
335 		if ( strcmp( param, "-if") == 0 || strcmp( param, "--issuer_file") == 0) {
336 			i++;
337 			if( i == argc) return print_usage( argv[0]);
338 			filename = argv[i];
339 		} else if( strcmp( param, "-dc") == 0 || strcmp( param, "--daa_counter") == 0){
340 			i++;
341 			if( i == argc) return print_usage( argv[0]);
342 			daaCounter = atoi(argv[i]);
343 		} else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){
344 			i++;
345 			if( i == argc) return print_usage( argv[0]);
346 			szTpmPasswd = argv[i];
347 		} else {
348 			fprintf(stderr, "\n%s:unrecognized option <%s>\n", argv[0], param);
349 			return print_usage( argv[0]);
350 		}
351 		i++;
352 	}
353 	bi_init( NULL);
354 
355 	// Create Context
356 	LogDebug("Create Context");
357 	result = Tspi_Context_Create( &hContext );
358 	if ( result != TSS_SUCCESS )
359 	{
360 		LogError( "Tspi_Context_Create %d\n", result );
361 		goto out;
362 	}
363 	// Connect to Context
364 	result = Tspi_Context_Connect( hContext, NULL );
365 	if ( result != TSS_SUCCESS) goto out_close;
366 	printf("\nConnect to the context: %X\n", hContext);
367 
368 	if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS)
369 		goto out_close;
370 	// Get the correct policy using the TPM ownership PASSWD
371 	if( (result = Tspi_GetPolicyObject( hTPM,
372 						TSS_POLICY_USAGE,
373 						&hPolicy)) != TSS_SUCCESS)
374 		goto out_close;
375 	if( (result = Tspi_Policy_SetSecret( hPolicy,
376 						TSS_SECRET_MODE_PLAIN,
377 						strlen( szTpmPasswd),
378 						szTpmPasswd)) != TSS_SUCCESS)
379 		goto out_close;
380 	LogDebug("Tspi_Policy_SetSecret hPolicy received;%d\n", hPolicy);
381 
382 	//Create Object
383 	result = obj_daa_add( hContext, &hDAA);
384 	if (result != TSS_SUCCESS) {
385 		LogError("Tspi_Context_CreateObject:%d\n", result);
386 		Tspi_Context_Close(hContext);
387 		LogError("%s: %s\n", argv[0], err_string(result));
388 		exit(result);
389 	}
390 	LogDebug("created DAA object:%X", hDAA);
391 	issuer = initIssuer( DEFAULT_KEY_CHAIN_LENGTH, filename, argv[0], hContext);
392 	if( issuer == NULL) goto out_close;
393 
394 	// generate receiver attributes and issuer attributes (random)
395 	attributesPlatformLength = issuer->pk->capitalRReceiver->length;
396 	attributesPlatform = (BYTE **)malloc( attributesPlatformLength * sizeof(BYTE *));
397 	bi_new( random);
398 	for( i=0; i<(int)attributesPlatformLength; i++) {
399 		bi_urandom( random, DAA_PARAM_SIZE_F_I);
400 		attributesPlatform[i] = bi_2_nbin( &length, random);
401 		if( attributesPlatform[i] == NULL) {
402 			LogError("malloc of %d bytes failed", length);
403 			result = TSPERR(TSS_E_OUTOFMEMORY);
404 			goto out_close;
405 		}
406 	}
407 	attributesIssuerLength = issuer->pk->capitalRIssuer->length;
408 	attributesIssuer = (BYTE **)malloc( attributesIssuerLength * sizeof(BYTE *));
409 	for( i=0; i<(int)attributesIssuerLength; i++) {
410 		bi_urandom( random, DAA_PARAM_SIZE_F_I);
411 		attributesIssuer[i]  = bi_2_nbin( &length, random);
412 		if( attributesIssuer[i] == NULL) {
413 			LogError("malloc of %d bytes failed", length);
414 			result = TSPERR(TSS_E_OUTOFMEMORY);
415 			goto out_close;
416 		}
417 	}
418 	bi_free(random);
419 	LogDebug("Generated attributes (Platform=%d,Issuer=%d)",
420 		attributesPlatformLength, attributesIssuerLength);
421 
422 	result = Tspi_TPM_DAA_JoinInit(
423 		hDAA,	// in
424 		hTPM,	// in
425 		daaCounter,	// in
426 		(TSS_HKEY)issuer->pk_extern,	// in
427 		issuer->length_key_chain,	// in
428 		(TSS_HKEY *)issuer->key_chain,	// in
429 		issuer->length_key_chain,	// in
430 		issuer->pk_signatures,	// in
431 		&capital_UPrimeLength,	// out
432 		&capitalUPrime,	// out
433 		&identityProof,	// out
434 		&joinSession	// out
435 	);
436 	if( result != TSS_SUCCESS) goto out_close;
437 
438 	result = Tspi_DAA_IssueInit(
439 		hDAA,	// in
440 		(TSS_HKEY)issuer->key_chain[0],	// in
441 		(TSS_HKEY)issuer->key_pair_extern,	// in
442 		identityProof,	// in
443 		capital_UPrimeLength,	// in
444 		capitalUPrime,	// in
445 		daaCounter,	// in
446 		&nonceIssuerLength,	// out
447 		&nonceIssuer,	// out
448 		&authenticationChallengeLength,	// out
449 		&authenticationChallenge,	// out
450 		&join_issuer_session	// out
451 	);
452 	if( result != TSS_SUCCESS) goto out_close;
453 
454 	result = Tspi_TPM_DAA_JoinCreateDaaPubKey(
455 		hDAA,	// in
456 		hTPM,	// in
457 		authenticationChallengeLength,	// in
458 		authenticationChallenge,	// in
459 		nonceIssuerLength,	// in
460 		nonceIssuer,	// in
461 		attributesPlatformLength,	// in
462 		attributesPlatform,	// in
463 		&joinSession,	// in & out
464 		&credentialRequest	// out
465 	);
466 	if( result != TSS_SUCCESS) goto out_close;
467 
468 	result = Tspi_DAA_IssueCredential(
469 		hDAA,	// in
470 		attributesIssuerLength,	// in
471 		attributesIssuer,	// in
472 		credentialRequest,	// in
473 		join_issuer_session,	// in
474 		&credIssuer	// out
475 	);
476 
477 	result = Tspi_TPM_DAA_JoinStoreCredential(
478 		hDAA,	// in
479 		hTPM,	// in
480 		credIssuer,	// in
481 		joinSession,	// in
482 		(TSS_HKEY*)&credentialRequest	// out
483 	);
484 	if( result != TSS_SUCCESS) goto out_close;
485 
486 	printf("Saving credential: %s ", credential_filename);
487 	file = fopen( credential_filename, "w");
488 	if( save_TSS_DAA_CREDENTIAL( file, &credentialRequest) != 0) {
489 		LogError( "[test_join]: Error when saving \'%s\': %s",
490 			credential_filename,
491 			strerror( errno));
492 		result = TSS_E_FAIL;
493 		goto out_close;
494 	}
495 	fclose( file);
496 	printf("Done\n");
497 
498 out_close:
499 	Tspi_Context_FreeMemory( hContext, NULL );
500 	Tspi_Context_Close( hContext );
501 out:
502 	bi_release();
503 	LogDebug("THE END result=%d:%s",result, err_string( result) );;
504 	return result;
505 }
506