summaryrefslogtreecommitdiff
path: root/src/tspi/daa
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
commitc3649a2def02c41d837ae1f79dda729ccb91e677 (patch)
treebea46dff212fdef977fe9094a70a939e8cc21885 /src/tspi/daa
downloadtrousers-upstream.tar.gz
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tspi/daa')
-rw-r--r--src/tspi/daa/Makefile.am31
-rw-r--r--src/tspi/daa/big_integer/bi.c237
-rw-r--r--src/tspi/daa/big_integer/bi_gmp.c261
-rw-r--r--src/tspi/daa/big_integer/bi_openssl.c181
-rw-r--r--src/tspi/daa/big_integer/test/Makefile.am9
-rw-r--r--src/tspi/daa/big_integer/test/multi_exp.c29
-rw-r--r--src/tspi/daa/big_integer/test/test.c296
-rw-r--r--src/tspi/daa/daa_anonymityrevocation/csencryption_result.c211
-rw-r--r--src/tspi/daa/daa_debug.c294
-rw-r--r--src/tspi/daa/daa_debug.h66
-rw-r--r--src/tspi/daa/daa_issuer/issue_credential.c787
-rw-r--r--src/tspi/daa/daa_issuer/issuer_init.c142
-rw-r--r--src/tspi/daa/daa_issuer/issuer_setup.c166
-rw-r--r--src/tspi/daa/daa_issuer/key_correctness_proof.c516
-rw-r--r--src/tspi/daa/daa_issuer/key_verification.c147
-rw-r--r--src/tspi/daa/daa_issuer/keypair_generator.c397
-rw-r--r--src/tspi/daa/daa_issuer/prime_gen.c327
-rw-r--r--src/tspi/daa/daa_parameter.c184
-rw-r--r--src/tspi/daa/daa_platform/platform.c2644
-rw-r--r--src/tspi/daa/daa_platform/test.c142
-rw-r--r--src/tspi/daa/daa_platform/test_join.c504
-rw-r--r--src/tspi/daa/daa_structs.c1317
-rw-r--r--src/tspi/daa/daa_verifier/test/Makefile.am7
-rw-r--r--src/tspi/daa/daa_verifier/verifier.c57
-rw-r--r--src/tspi/daa/daa_verifier/verifier_transaction.c873
-rw-r--r--src/tspi/daa/test_sign.c238
-rw-r--r--src/tspi/daa/utils/list.c66
27 files changed, 10129 insertions, 0 deletions
diff --git a/src/tspi/daa/Makefile.am b/src/tspi/daa/Makefile.am
new file mode 100644
index 0000000..b02bbde
--- /dev/null
+++ b/src/tspi/daa/Makefile.am
@@ -0,0 +1,31 @@
+bin_PROGRAMS=issuer_setup key_verification test test_tpm test_join test_sign
+#todel
+
+test_SOURCES=big_integer/bi_gmp.c big_integer/bi_openssl.c big_integer/bi.c utils/list.c big_integer/test/test.c big_integer/test/multi_exp.c
+test_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -g -DAPPID=\"BI\"
+test_LDFLAGS=-lcrypto
+
+issuer_setup_SOURCES = daa_issuer/issuer_setup.c
+issuer_setup_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_ISSUER_SETUP\"
+issuer_setup_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la
+
+key_verification_SOURCES=daa_issuer/key_verification.c
+key_verification_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_KEY_VERIFICATION\"
+key_verification_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la
+
+test_tpm_SOURCES = daa_platform/test.c
+test_tpm_CFLAGS=-I../../include/daa -I../../include
+test_tpm_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la
+
+test_join_SOURCES = daa_platform/test_join.c
+test_join_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_JOIN\"
+test_join_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la
+
+test_sign_SOURCES = test_sign.c
+test_sign_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_JOIN\"
+test_sign_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la
+
+#todel_SOURCES = todel.c
+#todel_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_JOIN\"
+#todel_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la
+
diff --git a/src/tspi/daa/big_integer/bi.c b/src/tspi/daa/big_integer/bi.c
new file mode 100644
index 0000000..b86b2c1
--- /dev/null
+++ b/src/tspi/daa/big_integer/bi.c
@@ -0,0 +1,237 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <bi.h>
+
+#include "tcslog.h"
+
+#undef INLINE_DECL
+#define INLINE_DECL
+
+/***********************************************************************************
+ CONSTANT
+*************************************************************************************/
+
+bi_t bi_0;
+bi_t bi_1;
+bi_t bi_2;
+
+/***********************************************************************************
+ WORK VARIABLE
+*************************************************************************************/
+
+// Buffer to load bi from a file . A static field is used, this should not be
+// refere in any SPI calls.
+#define BUFFER_SIZE 10000
+static char buffer[BUFFER_SIZE]; // used for loading bi
+
+#define SAFETY_PARAM 80
+
+// keep the list of allocated memory, usually used for the format functions
+list_ptr allocs = NULL;
+
+/***********************************************************************************
+ DUMP LIB
+*************************************************************************************/
+
+// !! to use only for debugging
+// do not used it in the same call, as a static buffer is used
+char *dump_byte_array(int len, unsigned char *array) {
+ int i, j=0;
+ char c, str[3];
+
+ for( i=0; i<len; i++) {
+ c = array[i];
+ sprintf( str, "%02X", (int)(c & 0xFF));
+ buffer[j] = str[0];
+ buffer[j+1] = str[1];
+ j+=2;
+ }
+ buffer[j] = 0;
+ return buffer;
+}
+
+/* convert <strings> and return it into a byte array <result> of length <length> */
+unsigned char *retrieve_byte_array( int *len, const char *strings) {
+ int index_str = 0, index_result = 0;
+ int str_len = strlen( strings);
+ char read_buffer[3];
+ int c;
+ unsigned char *result;
+
+ read_buffer[2]=0;
+ *len = ( str_len >> 1);
+ #ifdef BI_DEBUG
+ printf("[%s]\n", strings);
+ printf("[retrieve_byte_array] strlen=%d len=%d\n", str_len, *len);
+ #endif
+ result = (unsigned char *)malloc( *len+1);
+ if( result == NULL) {
+ LogError("malloc of %d bytes failed", *len+1);
+ return NULL;
+ }
+ if( (str_len & 1) ==1) {
+ // impair => 1 12 23 -> 01 12 23
+ read_buffer[0]='0';
+ read_buffer[1]=strings[index_str++];
+ sscanf( read_buffer, "%2X", &c);
+ #ifdef BI_DEBUG
+ printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer);
+ #endif
+ result[index_result++] = c&0xFF;
+ (*len)++;
+ }
+ while( index_str < str_len) {
+ read_buffer[0] = strings[ index_str++];
+ read_buffer[1] = strings[ index_str++];
+ sscanf( read_buffer, "%02X", &c);
+ #ifdef BI_DEBUG
+ printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer);
+ #endif
+ result[index_result++] = c&0xFF;
+ }
+ return result;
+}
+
+/* create a <big integer> array */
+INLINE_DECL void bi_new_array( bi_array array, const int length) {
+ int i=0;
+
+ bi_new_array2( array, length);
+ if( array->array == NULL) return;
+ for( i = 0; i< length; i++) {
+ array->array[i] = bi_new_ptr();
+ }
+}
+
+/* create a <big integer> array */
+INLINE_DECL void bi_new_array2( bi_array array, const int length) {
+ array->length = length;
+ array->array = (bi_ptr *)malloc( sizeof(bi_ptr) * length);
+ if( array->array == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(bi_ptr)*length);
+ return;
+ }
+}
+
+/* free resources allocated to the big integer <i> */
+INLINE_DECL void bi_free_array(bi_array array) {
+ int length = array->length;
+ int i=0;
+
+ for( i = 0; i< length; i++) {
+ bi_free_ptr( array->array[i]);
+ }
+ free( array->array);
+}
+
+/* copy length pointers from the array <src, offset_src> to array <dest, offset_dest> */
+INLINE_DECL void bi_copy_array(bi_array_ptr src,
+ int offset_src,
+ bi_array_ptr dest,
+ int offset_dest,
+ int length) {
+ int i=0;
+
+ for( i = 0; i< length; i++) {
+ dest->array[ offset_dest + i] = src->array[ offset_src + i];
+ }
+}
+
+/* debug function -> dump a field of type bi_array */
+void dump_bi_array( char *field, const bi_array_ptr array) {
+ int i;
+
+ for( i=0; i<array->length; i++) {
+ printf("%s->array[%d] = %s\n", field, i, bi_2_hex_char(array->array[i]));
+ }
+}
+
+/***********************************************************************************
+ SAFE RANDOM
+*************************************************************************************/
+
+/* Returns a random number in the range of [0,element-1] */
+bi_ptr compute_random_number( bi_ptr result, const bi_ptr element) {
+ bi_urandom( result, bi_length( element) + SAFETY_PARAM);
+ bi_mod( result, result, element);
+ return result;
+}
+
+/***********************************************************************************
+ SAVE / LOAD
+*************************************************************************************/
+
+/* load an big integer from an open file handler */
+void bi_load( bi_ptr bi, FILE *file) {
+ int i=0;
+ char c;
+
+ fgets( buffer, BUFFER_SIZE, file);
+ do {
+ c = buffer[i];
+ i++;
+ } while( c != 0 && c != ' ');
+ buffer[i-1] = 0;
+ bi_set_as_hex( bi, buffer);
+}
+
+/* load an big integer array from an open file handler */
+void bi_load_array( bi_array_ptr array, FILE *file) {
+ int i, j = 0, length;
+ char c;
+
+ fgets( buffer, BUFFER_SIZE, file);
+ do {
+ c = buffer[ j];
+ j++;
+ } while( c != 0 && c != ' ');
+ buffer[ j -1] = 0;
+ sscanf( buffer, "%d", &length);
+ bi_new_array( array, length);
+ for( i=0; i<array->length; i++) {
+ bi_load( array->array[i], file);
+ }
+}
+
+/* save an big integer to an open file handler */
+void bi_save( const bi_ptr bi, const char *name, FILE *file) {
+ fprintf( file, "%s # %s [%ld]\n", bi_2_hex_char( bi), name, bi_nbin_size( bi));
+}
+
+/* save an big integer array to an open file handler */
+void bi_save_array( const bi_array_ptr array, const char *name, FILE *file) {
+ int i;
+ char new_name[100];
+
+ fprintf(file, "%d # %s.length\n", array->length, name);
+ for( i=0; i<array->length; i++) {
+ sprintf( new_name, "%s[%d]", name, i);
+ bi_save( array->array[i], new_name, file);
+ }
+}
+
+/* convert <bi> to a byte array of length result, the beginning of */
+/* this buffer is feel with '0' if needed */
+void bi_2_byte_array( unsigned char *result, int length, bi_ptr bi) {
+ int i, result_length;
+
+ bi_2_nbin1( &result_length, buffer, bi);
+ int delta = length - result_length;
+ #ifdef BI_DEBUG
+ fprintf( stderr, "[bi_2_byte_array] result_length=%d length=%d\n", result_length, length);
+ #endif
+ if( delta < 0) {
+ LogError( "[bi_2_byte_array] asked length:%d found:%d\n", length, result_length);
+ return;
+ }
+ for( i=0; i<delta; i++) result[i] = 0;
+ for( ; i<length; i++) result[ i] = buffer[ i - delta];
+}
diff --git a/src/tspi/daa/big_integer/bi_gmp.c b/src/tspi/daa/big_integer/bi_gmp.c
new file mode 100644
index 0000000..f03bf4c
--- /dev/null
+++ b/src/tspi/daa/big_integer/bi_gmp.c
@@ -0,0 +1,261 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#ifdef BI_GMP
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <bi.h>
+
+#undef INLINE_DECL
+#define INLINE_DECL
+
+gmp_randstate_t state;
+
+/*
+ reps controls how many tests should be done in mpz_probable_prime_p:
+ 5 to 10 are reasonable number
+*/
+static int reps = 20;
+
+static int initialized = 0;
+void * (*bi_alloc)(size_t size);
+
+/***********************************************************************************
+ BITS OPERATION
+*************************************************************************************/
+
+// for conversion from and to byte[] see mpz_export and mpz_import
+
+/* return the size of a network byte order representation of <i> */
+long bi_nbin_size(const bi_ptr i) {
+ int word_size = 1; // 1 byte per word
+ int numb = 8 * word_size - 0;
+ int count = (mpz_sizeinbase ( i, 2) + numb-1) / numb;
+
+ return count * word_size;
+}
+
+/* return a BYTE * - in network byte order - and update the length <length> */
+unsigned char *bi_2_nbin( int *length, const bi_ptr i) {
+ unsigned char *buffer = (unsigned char *)bi_alloc( bi_nbin_size( i));
+
+ if( buffer == NULL) return NULL;
+ mpz_export(buffer, length, 1, 1, 1, 0, i);
+ return buffer;
+}
+
+/* return a BYTE * - in network byte order - and update the length <length> */
+/* different from bi_2_nbin: you should reserve enough memory for the storage */
+void bi_2_nbin1( int *length, unsigned char *buffer, const bi_ptr i) {
+ mpz_export(buffer, length, 1, 1, 1, 0, i);
+}
+
+/* return a bi_ptr that correspond to the big endian encoded BYTE array of length <n_length> */
+INLINE_DECL bi_ptr bi_set_as_nbin( const unsigned long length, const unsigned char *buffer) {
+ bi_ptr ret = bi_new_ptr();
+
+ if( ret == NULL) return NULL;
+ mpz_import( ret, length, 1, 1, 1, 0, buffer);
+ return ret;
+}
+
+
+/***********************************************************************************
+ BASIC MATH OPERATION
+*************************************************************************************/
+
+/* multiple-exponentiation */
+/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with 0 <= i <= <n> */
+bi_ptr bi_multi_mod_exp( bi_ptr result,
+ const int n,
+ const bi_t g[],
+ const long e[],
+ const int m) {
+ mpz_t temp, bi_m;
+ int i;
+
+ mpz_init( temp);
+ mpz_init( bi_m);
+ mpz_set_si( bi_m, m);
+ // result := (g[0] ^ e[0]) mod m
+ mpz_powm_ui( result, g[0], e[0], bi_m);
+ for( i=1; i<n; i++) {
+ // temp := (g[i] ^ e[i]) mod bi_m
+ mpz_powm_ui( temp, g[i], e[i], bi_m);
+ // result := result * temp
+ mpz_mul( result, result, temp);
+ }
+ mpz_mod_ui( result, result, m);
+ mpz_clear( bi_m);
+ mpz_clear( temp);
+ return result;
+}
+
+/***********************************************************************************
+ NUMBER THEORIE OPERATION
+*************************************************************************************/
+/* generate prime number of <length> bits */
+INLINE_DECL bi_ptr bi_generate_prime( bi_ptr result, const long length) {
+ do {
+ mpz_urandomb( result, state, length); // i := random( length)
+ bi_setbit( result, 0);
+ bi_setbit( result, length - 1);
+ bi_setbit( result, length - 2);
+ mpz_nextprime( result, result); // i := nextPrime( i)
+ } while( mpz_sizeinbase( result, 2) != (unsigned long)length &&
+ bi_is_probable_prime( result) );
+ return result;
+}
+
+/* generate a safe prime number of <length> bits */
+/* by safe we mean a prime p so that (p-1)/2 is also prime */
+INLINE_DECL bi_ptr bi_generate_safe_prime( bi_ptr result, long length) {
+ mpz_t temp;
+
+ mpz_init(temp);
+ do {
+ bi_generate_prime( result, length);
+ mpz_sub_ui( temp, result, 1); // temp := result - 1
+ mpz_div_2exp( temp, temp, 1); // temp := temp / 2
+ } while( mpz_probab_prime_p( temp, 10) == 0);
+#ifdef BI_DEBUG
+ printf("GENERATE SAFE PRIME DONE");fflush(stdout);
+#endif
+ mpz_clear( temp);
+ return result;
+}
+
+/* return true if <i> is a probably prime */
+INLINE_DECL int bi_is_probable_prime( bi_ptr i) {
+ /*
+ This function does some trial divisions and after some Miller-Rabin probabilistic
+ primality tests. The second parameter controls how many tests should be done,
+ 5 to 10 are reasonable number
+ */
+ return mpz_probab_prime_p( i, reps)>=1 ? 1 : 0;
+}
+
+/* return in <result> the greatest common divisor of <a> and <b> */
+/* <result> := gcd( <a>, <b>) */
+INLINE_DECL bi_ptr bi_gcd( bi_ptr result, bi_ptr a, bi_ptr b) {
+ // result := gcd( a, b)
+ mpz_gcd( result, a, b);
+ return result;
+}
+
+
+/***********************************************************************************
+ INIT/RELEASE LIBRARY
+*************************************************************************************/
+
+/* bi_alloc_p allocation function used only for exporting a bi struct, so for bi_2_nbin
+if define as NULL, a stdlib malloc() will be used */
+void bi_init( void * (*bi_alloc_p)(size_t size)) {
+ time_t start;
+ unsigned long seed;
+ FILE *f;
+#ifdef INTERACTIVE
+ int c, i;
+#endif
+
+ if( initialized == 1) return;
+ if( bi_alloc_p == NULL) bi_alloc = &malloc;
+ else bi_alloc = bi_alloc_p;
+ mpz_init( bi_0);
+ mpz_set_ui( bi_0, 0);
+ mpz_init( bi_1);
+ mpz_set_ui( bi_1, 1);
+ mpz_init( bi_2);
+ mpz_set_ui( bi_2, 2);
+ allocs = list_new();
+ if( allocs == NULL) {
+ LogError("malloc of list failed");
+ return;
+ }
+#ifdef BI_DEBUG
+ printf("bi_init() -> gmp lib\n");
+#endif
+ time( &start);
+ // first try /dev/random, the most secure random generator
+ f = fopen("/dev/random", "r");
+ // in case of failure, but les secure :(
+ if( f== NULL) f = fopen("/dev/urandom", "r");
+ if( f != NULL) {
+ fread( &seed, sizeof(unsigned long int), 1, f);
+ fclose(f);
+ }
+#ifdef INTERACTIVE
+ else {
+ printf("! devices /dev/random and /dev/urandom not found\n");
+ printf("type some characters to generate a random seed (follow by enter)\n");
+ fflush(stdout);
+ i=0;
+ while( (c = fgetc(stdin)) != 10) {
+ time_t temps;
+ time( &temps);
+ seed += temps +( c << i);
+ i++;
+ }
+ time_t temps;
+ time( &temps);
+ seed += temps;
+#ifdef BI_DEBUG
+ printf("temps=%lx\n", temps - start);
+#endif // BI_DEBUG
+ seed = (long)( temps * start);
+ }
+#endif // INTERACTIVE
+#ifdef BI_DEBUG
+ printf("seed=%lx\n", seed);
+#endif
+ gmp_randinit_default( state);
+ gmp_randseed_ui( state, seed);
+ initialized = 1;
+}
+
+void bi_release(void) {
+ if( initialized) {
+ bi_flush_memory();
+ bi_free( bi_0);
+ bi_free( bi_1);
+ bi_free( bi_2);
+ initialized = 0;
+ }
+}
+void bi_flush_memory(void) {
+ node_t *current;
+ list_ptr list = allocs;
+
+ if( list->head == NULL) return; // list is empty
+ else {
+ current = list->head; // go to first node
+ do {
+ LogDebug("[flush memory] free %lx\n", current->obj);
+ free( current->obj);
+ current = current->next; // traverse through the list
+ } while(current != NULL); // until current node is NULL
+ }
+ list_freeall( allocs);
+ allocs = list_new();
+ if( allocs == NULL) {
+ LogError("malloc of list failed");
+ return;
+ }
+}
+
+
+int bi_is_initialized(void) {
+ return initialized;
+}
+
+#endif
diff --git a/src/tspi/daa/big_integer/bi_openssl.c b/src/tspi/daa/big_integer/bi_openssl.c
new file mode 100644
index 0000000..50ef030
--- /dev/null
+++ b/src/tspi/daa/big_integer/bi_openssl.c
@@ -0,0 +1,181 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#ifdef BI_OPENSSL
+
+#define INSIDE_LIB
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <bi.h>
+
+#include "tcslog.h"
+
+#undef INLINE_DECL
+#define INLINE_DECL
+
+#include <string.h>
+#include <openssl/rand.h>
+
+BN_CTX *context;
+static int initialized = 0;
+
+void * (*bi_alloc)(size_t size);
+
+/* return true if <i> is a probably prime */
+INLINE_DECL int bi_is_probable_prime( const bi_ptr i) {
+ /*
+ * start tests using some small prime numbers. Continue by performing a Miller-Rabin
+ * probabilistic primality test with checks iterations, and with some iterations that
+ * yields a false positive rate of at most 2^-80 for random input.
+ * return:
+ * 0 if the number is composite
+ * 1 if it is prime with an error probability of less than 0.25^checks, and on error.
+ */
+ return BN_is_prime_fasttest( i, BN_prime_checks, NULL, context, NULL, 1);
+}
+
+/* <result> := ( <g> ^ <e> ) mod <m> */
+INLINE_DECL bi_ptr bi_mod_exp_si( bi_ptr result, const bi_ptr g, const bi_ptr e, const long m) {
+ bi_t bi_tmp;
+
+ bi_new( bi_tmp);
+ BN_set_word( bi_tmp, m);
+#ifdef BI_DEBUG
+ printf("[bi_mod_exp] (g=%s ^ e=%s) mod=%s\n",
+ BN_bn2dec( g),
+ BN_bn2dec( e),
+ BN_bn2dec( bi_tmp));
+#endif
+ BN_mod_exp( result, g, e, bi_tmp, context); // result := (g ^ e) mod bi_tmp9
+#ifdef BI_DEBUG
+ printf("[bi_mod_exp] res=%s\n", BN_bn2dec( result));
+#endif
+ bi_free( bi_tmp);
+ return result;
+}
+
+/* multiple-exponentiation */
+/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with 0 <= i <= <n> */
+bi_ptr bi_multi_mod_exp( bi_ptr result,
+ const int n,
+ const bi_t g[],
+ const long e[],
+ const int m
+) {
+ BIGNUM *temp = BN_new();
+ BIGNUM *bi_m = BN_new();
+ BIGNUM *bi_e = BN_new();
+ int i;
+
+ BN_set_word( bi_m, m);
+ BN_set_word( bi_e, e[0]);
+ // result := (g[0] ^ e[0]) mod bi_m
+ BN_mod_exp( result, g[0], bi_e, bi_m, context);
+ for( i=1; i<n; i++) {
+ BN_set_word( bi_e, e[i]);
+ // temp := (g[i] ^ e[i]) mod bi_m
+ BN_mod_exp( temp, g[i], bi_e, bi_m, context);
+ // result := result * temp
+ BN_mul( result, result, temp, context);
+ }
+ BN_mod( result, result, bi_m, context);
+ BN_free(bi_e);
+ BN_free(bi_m);
+ BN_free(temp);
+ return result;
+}
+
+
+/***********************************************************************************
+ INIT/RELEASE LIBRARY
+************************************************************************************/
+
+/* bi_alloc_p allocation function used only for exporting a bi struct,
+so for bi_2_nbin? for example. if define as NULL, a stdlib malloc() will be used
+*/
+void bi_init( void * (*bi_alloc_p)(size_t size)) {
+ if( initialized == 1) return;
+ if( bi_alloc_p == NULL) bi_alloc = &malloc;
+ else bi_alloc = bi_alloc_p;
+ bi_new( bi_0);
+ bi_set_as_si( bi_1, 0);
+ bi_new( bi_1);
+ bi_set_as_si( bi_1, 1);
+ bi_new( bi_2);
+ bi_set_as_si( bi_2, 2);
+ allocs = list_new();
+ if( allocs == NULL) {
+ LogError("malloc of list failed");
+ return;
+ }
+ LogDebug("bi_init() -> openssl lib\n");
+ LogDebug("bi_init() -> seed status = %d\n", RAND_status());
+ context = BN_CTX_new();
+ if( RAND_status() != 1) {
+ LogError("! PRNG has not been seeded with enough data\n");
+#ifdef INTERACTIVE
+ printf("type some characters to regenerate a random seed\n");
+ fflush(stdout);
+ int c, i=0, seed;
+ char str[2] = "a";
+ while( RAND_status() !=1 ) {
+ c = fgetc(stdin);
+ time_t temps;
+ time( &temps);
+ seed += temps +( c << i);
+ i++;
+ str[0]=c;
+ RAND_seed( str, 1);
+ }
+#endif
+ }
+ initialized = 1;
+}
+
+void bi_release(void) {
+ if( initialized) {
+ bi_flush_memory();
+ bi_free( bi_0);
+ bi_free( bi_1);
+ bi_free( bi_2);
+ BN_CTX_free( context);
+ initialized = 0;
+ }
+}
+
+void bi_flush_memory(void) {
+ node_t *current;
+ list_ptr list = allocs;
+
+ if( list->head == NULL) return; // list is empty
+ else {
+ current = list->head; // go to first node
+ do {
+ LogDebug("[flush memory] free %lx\n", (long)current->obj);
+ free( current->obj);
+ current = current->next; // traverse through the list
+ } while(current != NULL); // until current node is NULL
+ }
+ list_freeall( allocs);
+ allocs = list_new();
+ if( allocs == NULL) {
+ LogError("malloc of list failed");
+ return;
+ }
+}
+
+int bi_is_initialized(void) {
+ return initialized;
+}
+
+#endif
diff --git a/src/tspi/daa/big_integer/test/Makefile.am b/src/tspi/daa/big_integer/test/Makefile.am
new file mode 100644
index 0000000..d631c2a
--- /dev/null
+++ b/src/tspi/daa/big_integer/test/Makefile.am
@@ -0,0 +1,9 @@
+bin_PROGRAMS = test
+
+
+test_SOURCES=test.c multi_exp.c ../bi_gmp.c ../bi_openssl.c ../bi.c \
+ ../../../include/bi.h ../../../include/bi_openssl.h ../../../include/bi_gmp.h
+test_CFLAGS=-G
+
+# test_CFLAGS=-I../../../include -DBI_OPENSSL
+
diff --git a/src/tspi/daa/big_integer/test/multi_exp.c b/src/tspi/daa/big_integer/test/multi_exp.c
new file mode 100644
index 0000000..2ff80fc
--- /dev/null
+++ b/src/tspi/daa/big_integer/test/multi_exp.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+#include <bi.h>
+
+// use standard C definition to avoid .h
+int test_exp_multi(void) {
+ bi_t result;
+ bi_t g[3];
+ unsigned long e[3];
+
+ bi_new( result);
+ bi_new( g[0]);
+ bi_new( g[1]);
+ bi_new( g[2]);
+ // result = (2^2 * 5^4 * 7^7) mod 56 -> should give 28
+ bi_set_as_dec( g[0], "2");
+ bi_set_as_dec( g[1], "5");
+ bi_set_as_dec( g[2], "7");
+ e[0] = 2L;
+ e[1] = 4L;
+ e[2] = 7L;
+ bi_multi_mod_exp( result, 3, g, e, 56);
+ printf("multi-exponentiation <result>=%s\n", bi_2_dec_char(result));
+ bi_free( g[0]);
+ bi_free( g[1]);
+ bi_free( g[2]);
+ bi_free( result);
+ return 0;
+}
diff --git a/src/tspi/daa/big_integer/test/test.c b/src/tspi/daa/big_integer/test/test.c
new file mode 100644
index 0000000..4cc3a7f
--- /dev/null
+++ b/src/tspi/daa/big_integer/test/test.c
@@ -0,0 +1,296 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <bi.h>
+
+/* for the logging system used by TSS */
+setenv("TCSD_FOREGROUND", "1", 1);
+
+ /*
+ * standard bit length extension to obtain a uniformly distributed number
+ * [0,element]
+ */
+int test_exp_multi(void);
+
+void foo (bi_t result, const bi_ptr param, unsigned long n) {
+ unsigned long i;
+
+ bi_set( result, param);
+ bi_mul_si( result, result, n);
+ for (i = 1; i < n; i++) bi_add_si( result, result, i*7);
+}
+
+void *my_malloc(size_t size) {
+ void *ret = malloc( size);
+
+ printf("my_malloc() -> %ld\n", (long)ret);
+ return ret;
+}
+
+ /**
+ * Returns a random number in the range of [0,element-1].
+ *
+ * @param element
+ * the upper limit
+ * @param random
+ * the secure random source
+ * @return the random number
+ */
+void computeRandomNumber(bi_t res, const bi_ptr element) {
+ int length = 80 + bi_length( res); // give the length
+ bi_urandom( res, length); // res = random( of length);
+ int element_length = bi_length( element);
+ bi_mod_si( res, res, element_length); // res = res mod <number byte of element>
+}
+
+int main (int argc, char **argv) {
+ bi_t bi_tmp, bi_tmp1, bi_tmp2, bi_tmp3, bi_tmp4, bi_tmp5, bi_tmp6;
+ bi_t r;
+ bi_t n;
+ int i;
+ unsigned char result1[5];
+ int len;
+ char *byte_array;
+ FILE *file;
+ unsigned char ret[] = { (unsigned char)1, 0, (unsigned char)254 };
+ int length;
+ unsigned char *buffer;
+ unsigned char byte;
+ bi_ptr nn;
+
+ bi_init( &my_malloc);
+ printf("test(%s,%s)\n", __DATE__, __TIME__);
+ #ifdef BI_GMP
+ printf("using BMP\n");
+ #endif
+ #ifdef BI_OPENSSL
+ printf("using OPENSSL\n");
+ #endif
+
+ bi_new( bi_tmp);
+ bi_new( bi_tmp1);
+ bi_new( bi_tmp2);
+ bi_new( bi_tmp3);
+ bi_new( bi_tmp4);
+ bi_new( bi_tmp5);
+ bi_new( bi_tmp6);
+ bi_new( n);
+ bi_new( r);
+ bi_set_as_hex( n, "75E8F38669C531EB78C7ACD62CCDEFFB5E5BE15E2AA55B3AD28B1A35F6E937097CE09A49C689AC335FBA669205CEF209275CFF273F8F81C5B864E5029EECDFA0743BC15D6E4D2C2CB0DED2DC7119A7E0D61669D417BB3B12BA1D10FD40326A49CA6C9E77F8585F25D8C897D9C73284152E103582C018C964F02ADDBA56CB1161A949AAE2847ADE8BC1152716C8B4AF37A87011C2569F646FD3EDA83099048B9525A6401C47A372F3EA43C91066AD5851AE11DEF1EAC7108FFB06AD94D0B849C339A5E8793C4C054456D3D22D30ACCCF7EF33EF7A7D65799E7908D95B0538A9EFC91BF104CE5008D79625394DB1E5883B2F202B95320BBD868BF65C996FC0DFC5");
+ bi_set_as_hex( r, "35A624E6607CFD37162C6052547450B2267ECC749F10CDAEB5C294491321EEB47CA0229F423ADCEF3FA7806F5C4DB3C3445D8E7039EBC457149A1343BECF3B1078385C06EE74351A476BE0D5203633C81F7B8D68548DB763F0C096B20615B6016C180291EF32CC064A173BB22F6B46B3240ACC0B50D8338757FA28D5B0313BC4201CD2B35472842E71994C8FCA557B08004B2495304D13A93D796134BB8078E2EE371707DE5809D72474A7CCE1F865ECD8876105D3DB9AFA9426052D0120C755C60F56A0C0F30FAED2053CEB3129FAB6F57F6E209A8E7B2A559D734B339E19E1F2A147BC94DB2FF491CB5ACCEEEED7F2EA75AFF7CAD33E1E420A09135D9C5C1F");
+ DUMP_BI( n);
+ DUMP_BI( r);
+ printf("big number n=n*r\n");
+ bi_mul( n, n, r);
+ DUMP_BI( n);
+ bi_set_as_hex( r, "D7E7028DA181DADAC29C95143C865702453465115AFA7576AADF1E57DD84DA7FF4C8F66530D1E9D1AB69BC12342B89FA0A9755F9F4EE1DA445D50016CEF50622ED905CC9B987FCC7910CAA841641814C1994BC442A15CB05FE5C145626F1454E90435FBC6A529856EF29BDBCBFCB62FB69EDBD11DC33357667867278E1679EABCDBEEA02E9A6911804DF47ACA6B2D63A31E258AD542D71A8178A5E072F5E221EADBB10E16D5533AE427101FF94C5967575FABCD18305C5F15C103CEA1A8ACD01898E88426EDA7C0DF58AA48435808A840F6EEE1D7205D33F356E20FE0D4136B401BF386F11869C3CE4A808B96435694748EF3706F58756548A71E4CF4D2BE157");
+ bi_mod( n, n, r);
+ printf("mod big number n=n mod r\n");
+ DUMP_BI( n);
+ if( bi_get_si( bi_set_as_si( n, 13)) != 13) {
+ printf("!!! bi_set_as_si 13(%s) = 13\n", bi_2_dec_char( n ));
+ exit(-1);
+ }
+ if( bi_get_si( bi_set_as_si( n, -13)) != -13) {
+ printf("!!! bi_set_as_si -13(%s) = -13\n", bi_2_dec_char( n ));
+ exit(-1);
+ }
+ if( bi_get_si( bi_inc(bi_set_as_si( n, 13))) != 14) {
+ puts("!!! bi_inc 13++ = 14\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_dec(bi_set_as_si( n, 13))) != 12) {
+ puts("!!! bi_dec 13-- = 12\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_setbit(bi_set_as_si( n, 0), 10)) != 1024) {
+ puts("!!! bi_setbit set[10] = 1024\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_mod_si(bi_tmp, bi_set_as_si( n, 12), 10)) != 2) {
+ puts("!!! bi_mod_si 12 mod 10 = 2\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_mul_si(bi_tmp, bi_set_as_si( n, 12), 10)) != 120) {
+ puts("!!! bi_mul_si 12 * 10 = 120\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_mul(bi_tmp, bi_set_as_si( n, 12), bi_set_as_si( bi_tmp1, 10))) != 120) {
+ puts("!!! bi_mul_si 12 * 10 = 120\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_mod_exp_si(bi_tmp, bi_set_as_si( bi_tmp1, 4), bi_2, 10)) != 6) {
+ puts("!!! bi_mod_exp_si 4 ^ 2 mod 10 = 6\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_mod_exp(bi_tmp, bi_set_as_si( bi_tmp1, 4), bi_2, bi_set_as_si( bi_tmp2, 10))) != 6) {
+ puts("!!! bi_mod_exp 4 ^ 2 mod 10 = 6\n");
+ exit(-1);
+ }
+ if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, 12), bi_set_as_si(bi_tmp1, 10))) != 2) { printf("!!! bi_mod 12 mod 10 = 2 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); }
+ if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, -12), bi_set_as_si(bi_tmp1, 10))) != 8) { printf("!!! bi_mod -12 mod 10 = 8 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); }
+ if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, -27), bi_set_as_si(bi_tmp1, 10))) != 3) { printf("!!! bi_mod -27 mod 10 = 3 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); }
+ bi_set_as_si(n, 0x12345678);
+ bi_2_byte_array( result1, 5, n);
+ if( result1[0] != 0x00 || result1[1] != 0x12 || result1[2] != 0x34 || result1[3] != 0x56 || result1[4] != 0x78 ) {
+ printf("!!! bi_2_byte_array[0x123456578] [0]=%x [1]=%x [2]=%x [3]=%x [4]=%x \n", result1[0], result1[1], result1[2], result1[3], result1[4]);
+ exit( -1);
+ }
+ byte_array = retrieve_byte_array( &len, "12345");
+ printf("test dump_byte_array len=%d \n", len);
+ printf("test dump_byte_array(\"12345\")=%s\n", dump_byte_array( len, byte_array));
+ free( byte_array);
+ byte_array = retrieve_byte_array( &len, "12345678");
+ printf("test dump_byte_array len=%d \n", len);
+ printf("test dump_byte_array(\"12345678\")=%s\n", dump_byte_array( len, byte_array));
+
+ // test save end load of bi_t and bi_array
+ /////////////////////////////////////////////////////////////////////////////////////
+ bi_array result;
+ bi_new_array( result, 2);
+ bi_set_as_si( bi_tmp, 6);
+ bi_set_as_si( result->array[0], 314159);
+ bi_set_as_si( result->array[1], 123456789);
+ file = fopen("/tmp/test.todel", "w");
+ bi_save_array( result, "result", file);
+ bi_save( bi_tmp, "bi_tmp", file);
+ fclose( file);
+ bi_set_as_si( result->array[0], 0);
+ bi_set_as_si( result->array[1], 0);
+ bi_set_as_si( bi_tmp, 0);
+ file = fopen("/tmp/test.todel", "r");
+ bi_load_array( result, file);
+ bi_load( bi_tmp, file);
+ fclose( file);
+ if( bi_get_si( result->array[0]) != 314159) { puts("!!! save/load array[0] = 314159\n"); exit(-1); }
+ if( bi_get_si( result->array[1]) != 123456789) { puts("!!! save/load array[1] = 123456789\n"); exit(-1); }
+ if( bi_get_si( bi_tmp) != 6) { puts("!!! save/load bi_tmp = 6\n"); exit(-1); }
+
+ // conversion from bi_t 2 big endian BYTE*
+ /////////////////////////////////////////////////////////////////////////////////////
+ bi_set_as_si( n, 254+(1 << 16));
+ buffer = bi_2_nbin( &length, n);
+ printf("value 2 convert=%s length=%ld\n", bi_2_hex_char( n), bi_nbin_size( n));
+ for( i=0; i<length; i++) {
+ byte = (unsigned char)(buffer[i] & 0xFF);
+ if( byte != ret[i]) { printf("\n!!! bi_2_nbin[%d] %x = %x\n", i, byte, ret[i]); exit(-1); }
+ printf("[buffer[%d]=%x]", i, (int)(byte));
+ }
+ printf("\n");
+ nn = bi_set_as_nbin( length, buffer);
+ if( bi_equals_si( nn, 254+(1 << 16) ) == 0) {
+ printf("\n!!! bi_set_as_nbin %s = %x\n", bi_2_hex_char( nn), 254+(1 << 16));
+ exit(-1);
+ }
+ if( !bi_equals( bi_sub_si( bi_tmp, bi_set_as_si( bi_tmp1, 9), 1),
+ bi_mod( bi_tmp2,
+ bi_mul( bi_tmp3, bi_set_as_si(bi_tmp4, 6),
+ bi_set_as_si( bi_tmp5, 3)),
+ bi_set_as_si( bi_tmp6, 10)))) {
+ puts("!!! 9-1 == (6*3) mod 10\n");
+ printf("!!! tmp(8) = %s tmp1(9)=%s tmp2(8)=%s tmp3(6*3)=%s tmp4(6)=%s\
+ tmp5(3)=%s tmp6(10)=%s\n",
+ bi_2_dec_char(bi_tmp),
+ bi_2_dec_char(bi_tmp1),
+ bi_2_dec_char(bi_tmp2),
+ bi_2_dec_char(bi_tmp3),
+ bi_2_dec_char(bi_tmp4),
+ bi_2_dec_char(bi_tmp5),
+ bi_2_dec_char(bi_tmp6));
+ exit(-1);
+ puts("!!! 9-1 == (6*3) mod 10\n"); exit(-1);
+ }
+ bi_set_as_si(n, 1);
+ bi_shift_left(n, n, 10);
+ printf("1 << 10 = %s\n", bi_2_dec_char( n));
+ bi_set_as_si(n, 1);
+ printf("(1 << 10) >> 5 = %s\n", bi_2_dec_char( bi_shift_right(bi_tmp, bi_shift_left(bi_tmp1, n, 10), 5)));
+ bi_set_as_si(n, 1);
+ printf("[* (1 << 10) >> 5 *] = (2^10) / (2^5) -> %s\n", bi_2_dec_char( bi_shift_right( bi_tmp, ( bi_shift_left( bi_tmp1, n, 10)), 5)));
+ bi_set_as_si( n, 10);
+ printf(" (2^10) = %s\n", bi_2_dec_char( bi_mod_exp_si( bi_tmp, bi_2, n, 2000)));
+ printf(" (1<<5) = %s\n", bi_2_dec_char( bi_shift_left( bi_tmp, bi_set_as_si( bi_tmp1, 1), 5)));
+ printf(" 1024 / 500 = %s\n", bi_2_dec_char( bi_div( bi_tmp, bi_set_as_si( bi_tmp1, 1024), bi_set_as_si( bi_tmp2, 500))));
+ printf(" 1024 / 500 = %s\n", bi_2_dec_char( bi_div_si( bi_tmp, bi_set_as_si( bi_tmp1, 1024), 500)));
+ printf(" (1 << 10) >> 5 = [* (2^10) / (2^5) *] -> %s\n", bi_2_dec_char( bi_div( bi_tmp1,
+ bi_mod_exp_si( bi_tmp2, bi_2, bi_set_as_si( bi_tmp3, 10), 2000),
+ bi_mod_exp_si( bi_tmp4, bi_2, bi_set_as_si( bi_tmp5, 5), 2000) )));
+
+ printf("(1 << 10) >> 5 = (2^10) / (1<<5) -> %d\n", bi_equals( bi_shift_right( bi_tmp, ( bi_shift_left( bi_tmp1, bi_1, 10)), 5),
+ bi_div( bi_tmp2,
+ bi_mod_exp_si( bi_tmp3, bi_2, bi_set_as_si( bi_tmp4, 10), 2000),
+ bi_mod_exp_si( bi_tmp5, bi_2, bi_set_as_si( bi_tmp6, 5), 2000))));
+ printf("( 45 ^ -5 ) %% 10 == ( 1 / ( (45 ^ 5) %% 10) ) %% 10\n");
+ bi_set_as_si( bi_tmp, 45);
+ bi_set_as_si( bi_tmp1, 5);
+ // bi_negate( bi_tmp1);
+ bi_set_as_si( bi_tmp2, 10);
+ bi_mod_exp( bi_tmp3, bi_tmp, bi_tmp1, bi_tmp2);
+ bi_set_as_si( bi_tmp1, 5);
+ bi_mod_exp( bi_tmp4, bi_tmp, bi_tmp1, bi_tmp2);
+ printf("\t( 45 ^ -5 ) %% 10 = %s\n", bi_2_dec_char( bi_tmp3));
+ printf("\t( 1 / ( (45 ^ 5) %% 10) ) %% 10 = %s\n", bi_2_dec_char( bi_tmp4));
+ if( bi_equals( bi_tmp3, bi_tmp4) == 0) {
+ printf("!!! error !\n");
+ exit( -1);
+ }
+ for( i=0; i<5; i++) {
+ bi_generate_prime( bi_tmp, 1024);
+ printf("bi=%s\n", bi_2_hex_char( bi_tmp));
+ printf("bi.length=%ld \n", bi_length( bi_tmp));
+ if( bi_length( bi_tmp) != 1024) { puts("!!! length(random(1024)) != 1024\n"); exit(-1); }
+ }
+ bi_set_as_si(n, 0);
+ bi_setbit( n, 10);
+ printf("setbit(10) = %s\n", bi_2_dec_char( n));
+ bi_set_as_dec(n, "123456");
+ foo( r, n, 20L);
+ printf("TEST:%s\n", bi_2_dec_char( r));
+ bi_urandom( n, 1024);
+ bi_urandom( r, 1024);
+ computeRandomNumber( r, n);
+ printf("r:%s n:%s\n", bi_2_hex_char( r), bi_2_hex_char( n));
+ bi_generate_prime( r, 1024);
+ printf("prime:%s\nIs probable prime:%d\n", bi_2_hex_char( r), bi_is_probable_prime( r));
+ int error = bi_invert_mod( r, r, n);
+ printf("Invert mod return:%d\nInvert(r):%s\n", error, bi_2_hex_char( r));
+ bi_negate( r);
+ printf("negate(r):%s\n", bi_2_hex_char( r));
+ bi_generate_safe_prime( r, 128);
+ bi_sub_si( n, r, 1); // n= r - 1
+ bi_shift_right( n, n, 1); // n = n / 2
+ printf("safe prime(r):%s probable_prime:%d\n", bi_2_hex_char( r), bi_is_probable_prime( r));
+ printf("safe prime( (r-1)/2):%s probable_prime:%d\n", bi_2_hex_char( n), bi_is_probable_prime( n));
+ test_exp_multi();
+ bi_free( r);
+ bi_free( n);
+
+ bi_set_as_si( result->array[0], 1);
+ printf("result-> 1<<20:%s\n", bi_2_dec_char( bi_shift_left( result->array[0], result->array[0], 20)));
+ bi_set_as_si( result->array[1], 1);
+ printf("result1-> 1<<10:%s\n", bi_2_dec_char( bi_shift_right( result->array[1], result->array[0], 10)));
+ // copy arrays
+ bi_array new_result; bi_new_array2( new_result, 4);
+ bi_new_array2( new_result, 4);
+ bi_copy_array( result, 0, new_result, 0, 2);
+ bi_copy_array( result, 0, new_result, 2, 2);
+ for( i = 0; i<4; i++) {
+ printf("new_result[%d]-> [even-> 1<<20] [odd-> 1<<10] :%s\n", i, bi_2_dec_char( new_result->array[i]));
+ }
+
+ bi_free( bi_tmp);
+ bi_free( bi_tmp1);
+ bi_free( bi_tmp2);
+ bi_free( bi_tmp3);
+ bi_free( bi_tmp4);
+ bi_free( bi_tmp5);
+ bi_free( bi_tmp6);
+ bi_release();
+ printf("THE END [%s,%s]\n", __DATE__, __TIME__);
+ fflush(stdout);
+ return 0;
+
+}
+
diff --git a/src/tspi/daa/daa_anonymityrevocation/csencryption_result.c b/src/tspi/daa/daa_anonymityrevocation/csencryption_result.c
new file mode 100644
index 0000000..9750e7e
--- /dev/null
+++ b/src/tspi/daa/daa_anonymityrevocation/csencryption_result.c
@@ -0,0 +1,211 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include "daa_parameter.h"
+#include "daa_structs.h"
+#include "anonymity_revocation.h"
+#include "verifier.h"
+#include "tsplog.h"
+
+CS_ENCRYPTION_RESULT *create_CS_ENCRYPTION_RESULT(
+ bi_ptr c1,
+ bi_ptr c2,
+ bi_ptr c3,
+ bi_ptr c4
+) {
+ CS_ENCRYPTION_RESULT *result =
+ (CS_ENCRYPTION_RESULT *)malloc( sizeof(CS_ENCRYPTION_RESULT));
+
+ if (result == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(CS_ENCRYPTION_RESULT));
+ return NULL;
+ }
+ result->c1 = c1;
+ result->c2 = c2;
+ result->c3 = c3;
+ result->c4 = c4;
+ return result;
+}
+
+CS_ENCRYPTION_RESULT_RANDOMNESS *create_CS_ENCRYPTION_RESULT_RANDOMNESS(
+ CS_ENCRYPTION_RESULT *cs_encryption_result,
+ bi_ptr randomness
+) {
+ CS_ENCRYPTION_RESULT_RANDOMNESS *result =
+ (CS_ENCRYPTION_RESULT_RANDOMNESS *)
+ malloc(sizeof(CS_ENCRYPTION_RESULT_RANDOMNESS));
+
+ if (result == NULL) {
+ LogError("malloc of %d bytes failed",
+ sizeof(CS_ENCRYPTION_RESULT_RANDOMNESS));
+ return NULL;
+ }
+ result->randomness = randomness;
+ result->result = cs_encryption_result;
+ return result;
+}
+
+bi_ptr compute_u( const EVP_MD *digest,
+ const bi_ptr c1,
+ const bi_ptr c2,
+ const bi_ptr c3,
+ const BYTE *condition,
+ const int conditionLength
+) {
+ BYTE *buffer, *bytes;
+ int c1_size = bi_nbin_size( c1);
+ int c2_size = bi_nbin_size( c2);
+ int c3_size = bi_nbin_size( c3);
+ int index = 0;
+ int length;
+ bi_ptr value;
+ int bufferLength = c1_size + c2_size + c3_size + conditionLength;
+
+ buffer = (BYTE *)malloc( bufferLength);
+ if (buffer == NULL) {
+ LogError("malloc of %d bytes failed", bufferLength);
+ return NULL;
+ }
+ bi_2_byte_array( &buffer[index], c1_size, c1);
+ index += c1_size;
+ bi_2_byte_array( &buffer[index], c2_size, c2);
+ index += c2_size;
+ bi_2_byte_array( &buffer[index], c3_size, c3);
+ index += c3_size;
+ memcpy( &buffer[index], condition, conditionLength);
+ index += conditionLength;
+ length = DAA_PARAM_LENGTH_MFG1_ANONYMITY_REVOCATION / 8; // 25 /8
+ bytes = compute_bytes( bufferLength, buffer, length, digest);
+ if( bytes == NULL) return NULL;
+ value = bi_set_as_nbin( length, bytes);
+ free( bytes);
+ free( buffer);
+ return value;
+}
+
+CS_ENCRYPTION_RESULT_RANDOMNESS* internal_compute_encryption_proof(
+ const bi_ptr msg,
+ const bi_ptr delta1,
+ const bi_ptr delta2,
+ const bi_ptr delta3,
+ const bi_ptr randomness,
+ const CS_PUBLIC_KEY *key,
+ const struct tdTSS_DAA_PK_internal *daa_key,
+ const BYTE *condition,
+ const int conditionLength,
+ const EVP_MD *digest
+) {
+ bi_ptr modulus = daa_key->modulus;
+ bi_ptr gamma = daa_key->gamma;
+ bi_ptr c1 = bi_new_ptr( );
+ bi_ptr c2 = bi_new_ptr( );
+ bi_ptr c3 = bi_new_ptr( );
+ bi_ptr c4;
+ bi_ptr exp;
+ bi_t bi_tmp;
+ bi_t bi_tmp1;
+
+ bi_new( bi_tmp);
+ bi_new( bi_tmp1);
+ if( bi_cmp( msg, modulus) >= 0) {
+ LogError("IllegalArgument: msg to big for key size");
+ bi_free_ptr( c1);
+ bi_free_ptr( c2);
+ bi_free_ptr( c3);
+ bi_free( bi_tmp);
+ bi_free( bi_tmp1);
+ return NULL;
+ }
+ bi_mod_exp( c1, gamma, randomness, modulus);
+ bi_mod_exp( c2, key->eta, randomness, modulus);
+ // c3=msg * (key->lambda3 ^ randomness) % mopdulus)
+ bi_mul( c3, msg, bi_mod_exp( bi_tmp, key->lambda3, randomness, modulus));
+ bi_mod( c3, c3, modulus); // c3 = c3 % modulus
+ if( delta1 != NULL) {
+ if( !( delta2!=NULL && delta3!=NULL)) {
+ LogError("Illegal Arguments: delta2==NULL or delta3==NULL");
+ bi_free_ptr( c1);
+ bi_free_ptr( c2);
+ bi_free_ptr( c3);
+ bi_free( bi_tmp);
+ bi_free( bi_tmp1);
+ return NULL;
+ }
+ exp = compute_u( digest, delta1, delta2, delta3, condition, conditionLength);
+ } else {
+ if( !( delta2==NULL && delta3==NULL)) {
+ LogError("Illegal Arguments: delta2!=NULL or delta3!=NULL");
+ bi_free_ptr( c1);
+ bi_free_ptr( c2);
+ bi_free_ptr( c3);
+ bi_free( bi_tmp);
+ bi_free( bi_tmp1);
+ return NULL;
+ }
+ exp = compute_u( digest, c1, c2, c3, condition, conditionLength);
+ }
+ // exp = exp * randomness
+ bi_mul( exp, exp, randomness);
+ // exp = exp % daa_key->rho
+ bi_mod( exp, exp, daa_key->rho);
+ // bi_tmp = (key->lambda1 ^ randomness) % modulus
+ bi_mod_exp( bi_tmp, key->lambda1, randomness, modulus);
+ // bi_tmp1 = (key->lambda2 ^ exp) % modulus
+ bi_mod_exp( bi_tmp1, key->lambda2, exp, modulus);
+ c4 = bi_new_ptr();
+ // c4 = bi_tmp * bi_tmp1
+ bi_mul( c4, bi_tmp, bi_tmp1);
+ // c4 = c4 % modulus
+ bi_mod( c4, c4, modulus);
+ bi_free_ptr( exp);
+ bi_free( bi_tmp1);
+ bi_free( bi_tmp);
+ return create_CS_ENCRYPTION_RESULT_RANDOMNESS(
+ create_CS_ENCRYPTION_RESULT( c1, c2, c3, c4),
+ randomness);
+}
+
+/*
+Cramer-Shoup EncryptionProof
+from com.ibm.zurich.tcg.daa.anonymityrevocation.CSEncryptionProof
+ */
+CS_ENCRYPTION_RESULT_RANDOMNESS *compute_ecryption_proof(
+ const bi_ptr msg,
+ const bi_ptr delta1,
+ const bi_ptr delta2,
+ const bi_ptr delta3,
+ const bi_ptr randomness,
+ const CS_PUBLIC_KEY *key,
+ const struct tdTSS_DAA_PK_internal *daa_key,
+ const BYTE *condition,
+ const int conditionLength,
+ const EVP_MD *digest
+) {
+ if( delta1 == NULL || delta2 == NULL || delta3 == NULL) {
+ LogError("Illegal Argument: deltas (delta1:%ld delta2:%ld delta3:%ld)",
+ (long)delta1, (long)delta2, (long)delta3);
+ return NULL;
+ }
+ if( bi_cmp( randomness, daa_key->rho) >=0 || bi_cmp_si( randomness, 0) < 0) {
+ LogError("randomness >= rho || randomness < 0 \n\trandomness:%s\n\trho:%s\n",
+ bi_2_dec_char( randomness), bi_2_dec_char( daa_key->rho));
+ return NULL;
+ }
+ return internal_compute_encryption_proof( msg,
+ delta1,
+ delta2,
+ delta3,
+ randomness,
+ key,
+ daa_key,
+ condition,
+ conditionLength,
+ digest);
+}
diff --git a/src/tspi/daa/daa_debug.c b/src/tspi/daa/daa_debug.c
new file mode 100644
index 0000000..d39273b
--- /dev/null
+++ b/src/tspi/daa/daa_debug.c
@@ -0,0 +1,294 @@
+
+
+/********************************************************************************************
+* KEY PAIR WITH PROOF
+********************************************************************************************/
+
+int
+save_KEY_PAIR_WITH_PROOF(FILE *file,
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof)
+{
+ save_DAA_PK_internal( file, key_pair_with_proof->pk);
+ save_DAA_PRIVATE_KEY( file, key_pair_with_proof->private_key);
+ save_DAA_PK_PROOF_internal( file, key_pair_with_proof->proof);
+
+ return 0;
+}
+
+KEY_PAIR_WITH_PROOF_internal *
+load_KEY_PAIR_WITH_PROOF(FILE *file)
+{
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof =
+ (KEY_PAIR_WITH_PROOF_internal *)malloc(sizeof(KEY_PAIR_WITH_PROOF_internal));
+
+ key_pair_with_proof->pk = load_DAA_PK_internal(file);
+ key_pair_with_proof->private_key = load_DAA_PRIVATE_KEY(file);
+ key_pair_with_proof->proof = load_DAA_PK_PROOF_internal(file);
+
+ return key_pair_with_proof;
+}
+
+int
+save_DAA_PK_internal(FILE *file, const TSS_DAA_PK_internal *pk_internal)
+{
+ char *buffer;
+
+ LogDebug("-> save_DAA_PK_internal");
+
+ BI_SAVE( pk_internal->modulus, file);
+ BI_SAVE( pk_internal->capitalS, file);
+ BI_SAVE( pk_internal->capitalZ, file);
+ BI_SAVE( pk_internal->capitalR0, file);
+ BI_SAVE( pk_internal->capitalR1, file);
+ BI_SAVE( pk_internal->gamma, file);
+ BI_SAVE( pk_internal->capitalGamma, file);
+ BI_SAVE( pk_internal->rho, file);
+ BI_SAVE_ARRAY( pk_internal->capitalRReceiver, file);
+ BI_SAVE_ARRAY( pk_internal->capitalRIssuer, file);
+ fprintf( file, "%d\n", pk_internal->issuerBaseNameLength);
+ buffer = (char *)malloc( pk_internal->issuerBaseNameLength + 1);
+ memcpy( buffer, pk_internal->issuerBaseName, pk_internal->issuerBaseNameLength);
+ buffer[ pk_internal->issuerBaseNameLength] = 0;
+ fprintf( file, "%s\n", buffer);
+ free( buffer);
+
+ LogDebug("<- save_DAA_PK_internal");
+
+ return 0;
+}
+
+TSS_DAA_PK_internal *
+load_DAA_PK_internal(FILE *file)
+{
+ TSS_DAA_PK_internal *pk_internal =
+ (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal));
+ char *read_buffer;
+
+ pk_internal->modulus = bi_new_ptr();
+ BI_LOAD( pk_internal->modulus, file);
+ pk_internal->capitalS = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalS, file);
+ pk_internal->capitalZ = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalZ, file);
+ pk_internal->capitalR0 = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalR0, file);
+ pk_internal->capitalR1 = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalR1, file);
+ pk_internal->gamma = bi_new_ptr();
+ BI_LOAD( pk_internal->gamma, file);
+ pk_internal->capitalGamma = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalGamma, file);
+ pk_internal->rho = bi_new_ptr();
+ BI_LOAD( pk_internal->rho, file);
+ pk_internal->capitalRReceiver = ALLOC_BI_ARRAY();
+ BI_LOAD_ARRAY( pk_internal->capitalRReceiver, file);
+ pk_internal->capitalRIssuer = ALLOC_BI_ARRAY();
+ BI_LOAD_ARRAY( pk_internal->capitalRIssuer, file);
+ pk_internal->capitalY = ALLOC_BI_ARRAY();
+ populate_capitalY( pk_internal);
+ pk_internal->issuerBaseNameLength = read_int( file);
+ read_buffer = read_str( file);
+ pk_internal->issuerBaseName = malloc( pk_internal->issuerBaseNameLength);
+ memcpy( pk_internal->issuerBaseName, read_buffer, pk_internal->issuerBaseNameLength);
+ compute_capitalSprime( pk_internal);
+ return pk_internal;
+}
+
+int
+save_DAA_PK_PROOF_internal(FILE *file, TSS_DAA_PK_PROOF_internal *proof)
+{
+ int i;
+
+#ifdef DAA_DEBUG
+ printf("save_DAA_PK_PROOF_internal");
+#endif
+ fprintf(file, "%d # %s.length\n", proof->length_challenge, "challenge");
+ fprintf(file, "%s\n", dump_byte_array( proof->length_challenge,
+ proof->challenge));
+ fprintf(file, "%d # %s.length\n", proof->length_response, "response");
+ for (i = 0; i < proof->length_response; i++) {
+ BI_SAVE_ARRAY( proof->response[i], file);
+ }
+
+ return 0;
+}
+
+/* load <proof> using <filename> */
+/* allocation of: */
+/* proof->challenge (BYTE*) */
+/* response (bi_array_ptr) */
+TSS_DAA_PK_PROOF_internal *
+load_DAA_PK_PROOF_internal(FILE *file)
+{
+ TSS_DAA_PK_PROOF_internal *proof =
+ (TSS_DAA_PK_PROOF_internal *)malloc(sizeof(TSS_DAA_PK_PROOF_internal));
+ char *read_buffer;
+ int i;
+
+#ifdef DAA_DEBUG
+ printf("load_DAA_PK_PROOF_internal");
+#endif
+ proof->length_challenge = read_int( file);
+ read_buffer = read_str( file);
+ proof->challenge = retrieve_byte_array( &(proof->length_challenge),read_buffer);
+ proof->length_response = read_int( file);
+ proof->response = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * proof->length_response);
+ for (i = 0; i < proof->length_response; i++) {
+ proof->response[i] = ALLOC_BI_ARRAY();
+ BI_LOAD_ARRAY( proof->response[i], file);
+ }
+ return proof;
+}
+
+TSS_DAA_CRED_ISSUER *
+load_TSS_DAA_CRED_ISSUER(FILE *file)
+{
+ TSS_DAA_CRED_ISSUER *credential =
+ (TSS_DAA_CRED_ISSUER *)malloc(sizeof(TSS_DAA_CRED_ISSUER));
+ char *read_buffer;
+ int i, len;
+
+ init_tss_version( credential);
+ credential->capitalALength = read_int( file);
+ read_buffer = read_str( file);
+ credential->capitalA = retrieve_byte_array( &(credential->capitalALength),
+ read_buffer);
+ credential->eLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->e = retrieve_byte_array( &(credential->eLength),read_buffer);
+ credential->vPrimePrimeLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->vPrimePrime = retrieve_byte_array(&(credential->vPrimePrimeLength),
+ read_buffer);
+ // attributes issuer
+ credential->attributesIssuerLength = read_int( file);
+ credential->attributesIssuer = malloc(credential->attributesIssuerLength*sizeof(BYTE*));
+ for( i=0; i < (int)credential->attributesIssuerLength; i++) {
+ credential->attributesIssuer[i] = retrieve_byte_array( &len, read_buffer);
+ }
+ credential->cPrimeLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->cPrime = retrieve_byte_array( &(credential->cPrimeLength),read_buffer);
+ credential->sELength = read_int( file);
+ read_buffer = read_str( file);
+ credential->sE = retrieve_byte_array( &(credential->sELength),read_buffer);
+ return credential;
+}
+
+int
+save_TSS_DAA_CRED_ISSUER(FILE *file, TSS_DAA_CRED_ISSUER *credential)
+{
+ int i;
+
+ fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA");
+ fprintf(file, "%s\n", dump_byte_array( credential->capitalALength,
+ credential->capitalA));
+ fprintf(file, "%d # %s.length\n", credential->eLength, "e");
+ fprintf(file, "%s\n", dump_byte_array( credential->eLength,
+ credential->e));
+ fprintf(file, "%d # %s.length\n", credential->vPrimePrimeLength, "vPrimePrime");
+ fprintf(file, "%s\n", dump_byte_array( credential->vPrimePrimeLength,
+ credential->vPrimePrime));
+ fprintf(file, "%d # %s\n", credential->attributesIssuerLength, "attributesIssuerLength");
+ for( i=0; i < (int)credential->attributesIssuerLength; i++) {
+ fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8,
+ credential->attributesIssuer[i]));
+
+ }
+ fprintf(file, "%d # %s.length\n", credential->cPrimeLength, "cPrime");
+ fprintf(file, "%s\n", dump_byte_array( credential->cPrimeLength,
+ credential->cPrime));
+ fprintf(file, "%d # %s.length\n", credential->sELength, "sE");
+ fprintf(file, "%s\n", dump_byte_array( credential->sELength,
+ credential->sE));
+ return 0;
+}
+
+TSS_DAA_CREDENTIAL *
+load_TSS_DAA_CREDENTIAL(FILE *file)
+{
+ TSS_DAA_CREDENTIAL *credential =
+ (TSS_DAA_CREDENTIAL *)malloc(sizeof(TSS_DAA_CREDENTIAL));
+ char *read_buffer;
+ int i, len;
+ TSS_DAA_PK_internal *pk_internal;
+ TSS_DAA_PK *pk;
+
+ init_tss_version( credential);
+ credential->capitalALength = read_int( file);
+ read_buffer = read_str( file);
+ credential->capitalA = retrieve_byte_array( &(credential->capitalALength),
+ read_buffer);
+ credential->exponentLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->exponent = retrieve_byte_array( &(credential->exponentLength),
+ read_buffer);
+ credential->vBar0Length = read_int( file);
+ read_buffer = read_str( file);
+ credential->vBar0 = retrieve_byte_array(&(credential->vBar0Length),
+ read_buffer);
+ credential->vBar1Length = read_int( file);
+ read_buffer = read_str( file);
+ credential->vBar1 = retrieve_byte_array(&(credential->vBar1Length),
+ read_buffer);
+ // attributes issuer
+ credential->attributesLength = read_int( file);
+ printf("attributesLength=%d\n", credential->attributesLength);
+ credential->attributes = malloc(credential->attributesLength * sizeof( BYTE *));
+ for( i=0; i < (int)credential->attributesLength; i++) {
+ read_buffer = read_str( file);
+ credential->attributes[i] = retrieve_byte_array( &len, read_buffer);
+ if( len != DAA_PARAM_SIZE_F_I / 8) {
+ LogError("Error when parsing attributes");
+ LogError("\tattribute length:%d", len);
+ LogError("\texpected length:%d", DAA_PARAM_SIZE_F_I / 8);
+ return NULL;
+ }
+ }
+ pk_internal = load_DAA_PK_internal( file);
+ pk = i_2_e_TSS_DAA_PK( pk_internal, &normal_malloc, (TSS_HOBJECT)NULL);
+ memcpy( &(credential->issuerPK), pk, sizeof(TSS_DAA_PK));
+ free( pk);
+ free_TSS_DAA_PK_internal( pk_internal);
+ credential->tpmSpecificEncLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->tpmSpecificEnc = retrieve_byte_array( &(credential->tpmSpecificEncLength),
+ read_buffer);
+ credential->daaCounter = read_int( file);
+ return credential;
+}
+
+int
+save_TSS_DAA_CREDENTIAL(FILE *file,
+ TSS_DAA_CREDENTIAL *credential)
+{
+ int i;
+ TSS_DAA_PK_internal *pk_internal;
+
+ fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA");
+ fprintf(file, "%s\n", dump_byte_array( credential->capitalALength,
+ credential->capitalA));
+ fprintf(file, "%d # %s.length\n", credential->exponentLength, "exponent");
+ fprintf(file, "%s\n", dump_byte_array( credential->exponentLength,
+ credential->exponent));
+ fprintf(file, "%d # %s.length\n", credential->vBar0Length, "vBar0");
+ fprintf(file, "%s\n", dump_byte_array( credential->vBar0Length,
+ credential->vBar0));
+ fprintf(file, "%d # %s.length\n", credential->vBar1Length, "vBar1");
+ fprintf(file, "%s\n", dump_byte_array( credential->vBar1Length,
+ credential->vBar1));
+ fprintf(file, "%d # %s\n", credential->attributesLength, "attributesLength");
+ for( i=0; i < (int)credential->attributesLength; i++) {
+ fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8,
+ credential->attributes[i]));
+ }
+ pk_internal = e_2_i_TSS_DAA_PK( &(credential->issuerPK) );
+ save_DAA_PK_internal( file, pk_internal);
+ free_TSS_DAA_PK_internal( pk_internal);
+ fprintf(file, "%d # %s.length\n", credential->tpmSpecificEncLength, "tpmSpecificEnc");
+ fprintf(file, "%s\n", dump_byte_array( credential->tpmSpecificEncLength,
+ credential->tpmSpecificEnc));
+ fprintf(file, "%d # daaCounter\n", credential->daaCounter);
+ return 0;
+}
+
diff --git a/src/tspi/daa/daa_debug.h b/src/tspi/daa/daa_debug.h
new file mode 100644
index 0000000..368dd3d
--- /dev/null
+++ b/src/tspi/daa/daa_debug.h
@@ -0,0 +1,66 @@
+
+/********************************************************************************************
+ * KEY PAIR WITH PROOF
+ ********************************************************************************************/
+
+typedef struct tdKEY_PAIR_WITH_PROOF_internal {
+ TSS_DAA_PK_internal *pk;
+ DAA_PRIVATE_KEY_internal *private_key;
+ TSS_DAA_PK_PROOF_internal *proof;
+} KEY_PAIR_WITH_PROOF_internal;
+
+int save_KEY_PAIR_WITH_PROOF(
+ FILE *file,
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof
+);
+
+KEY_PAIR_WITH_PROOF_internal *load_KEY_PAIR_WITH_PROOF(
+ FILE *file
+);
+
+TSS_DAA_KEY_PAIR *get_TSS_DAA_KEY_PAIR(
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof,
+ void * (*daa_alloc)(size_t size, TSS_HOBJECT object),
+ TSS_HOBJECT param_alloc
+);
+
+
+int save_DAA_PK_internal(
+ FILE *file,
+ const TSS_DAA_PK_internal *pk_internal
+);
+
+TSS_DAA_PK_internal *load_DAA_PK_internal(
+ FILE *file
+);
+
+int save_DAA_PRIVATE_KEY(
+ FILE *file,
+ const DAA_PRIVATE_KEY_internal *private_key
+);
+
+DAA_PRIVATE_KEY_internal *load_DAA_PRIVATE_KEY(
+ FILE *file
+);
+
+int save_DAA_PK_PROOF_internal(
+ FILE *file,
+ TSS_DAA_PK_PROOF_internal *pk_internal
+);
+
+TSS_DAA_PK_PROOF_internal *load_DAA_PK_PROOF_internal(
+ FILE *file
+);
+
+TSS_DAA_CRED_ISSUER *load_TSS_DAA_CRED_ISSUER( FILE *file);
+
+int save_TSS_DAA_CRED_ISSUER( FILE *file, TSS_DAA_CRED_ISSUER *credential);
+
+TSS_DAA_CREDENTIAL *load_TSS_DAA_CREDENTIAL( FILE *file);
+
+int save_TSS_DAA_CREDENTIAL(
+ FILE *file,
+ TSS_DAA_CREDENTIAL *credential
+);
+
+
diff --git a/src/tspi/daa/daa_issuer/issue_credential.c b/src/tspi/daa/daa_issuer/issue_credential.c
new file mode 100644
index 0000000..0602dcb
--- /dev/null
+++ b/src/tspi/daa/daa_issuer/issue_credential.c
@@ -0,0 +1,787 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// for message digest
+#include <openssl/evp.h>
+
+#include <stdlib.h>
+#include "daa_structs.h"
+#include "daa_parameter.h"
+#include "trousers/tss.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include <trousers/trousers.h>
+#include <spi_utils.h>
+#include <obj.h>
+#include "tsplog.h"
+#include "tss/tcs.h"
+#include "platform.h"
+// to include compute_zeta
+#include "verifier.h"
+
+// from UBigInteger (computePrime)
+// remark: the type bi_t (bi_ptr) can not used a certaintity for probable_prime
+// as used in UbigInteger. (certaintity: DAA_PARAM_SAFETY)
+void compute_prime( bi_ptr e, int length, int interval) {
+ do {
+ bi_urandom( e, interval - 1);
+ bi_setbit( e, length - 1);
+ } while( bi_is_probable_prime( e) == 0);
+}
+
+/*
+ code derived from verifyAuthenticity (IssuerTransaction.java)
+*/
+TSS_RESULT verify_authentificity(TSS_DAA_CREDENTIAL_REQUEST *credentialRequest,
+ TSS_DAA_JOIN_ISSUER_SESSION *joinSession) {
+ EVP_MD_CTX mdctx;
+ BYTE *modulus_N0_bytes;
+ BYTE *digest_n0;
+ BYTE *contextHash;
+ BYTE *capitalUPrime_bytes;
+ BYTE *hash;
+ UINT32 digest_n0Length, contextHashLength, hashLength, daaCount;
+ bi_ptr capitalUPrime =NULL;
+ bi_ptr modulus_N0 = NULL;
+ TSS_RESULT result = TSS_SUCCESS;
+ char *buffer;
+
+ modulus_N0 = bi_new_ptr();
+ buffer = BN_bn2hex( ((RSA *)joinSession->issuerAuthPK)->n);
+ if( buffer == NULL) {
+ LogError("malloc of hexadecimal representation failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set_as_hex( modulus_N0, buffer);
+ // in TPM, N0 is hashed by hashing the scratch (256 bytes) so it must
+ // be formatted according to the scratch size (TPM_DAA_SIZE_issuerModulus)
+ modulus_N0_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus);
+ if (modulus_N0_bytes == NULL) {
+ LogError("malloc of %d bytes failed", TPM_DAA_SIZE_issuerModulus);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_byte_array( modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus, modulus_N0);
+ bi_free_ptr( modulus_N0);
+
+ if( TPM_DAA_SIZE_issuerModulus * 8 != DAA_PARAM_KEY_SIZE) {
+ LogError("TPM_DAA_SIZE_issuerModulus * 8 (%d) != DAA_PARAM_KEY_SIZE(%d)",
+ TPM_DAA_SIZE_issuerModulus*8, DAA_PARAM_KEY_SIZE);
+ return TSS_E_INTERNAL_ERROR;
+ }
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ // digestN0 = hash( modulus_N0) see Appendix B of spec. and TPM join stage 7 and 8
+ EVP_DigestUpdate(&mdctx, modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus);
+ digest_n0Length = EVP_MD_CTX_size(&mdctx);
+ digest_n0 = (BYTE *)malloc( digest_n0Length);
+ if (digest_n0 == NULL) {
+ LogError("malloc of %d bytes failed", digest_n0Length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ EVP_DigestFinal(&mdctx, digest_n0, NULL);
+
+ // test if credentialRequest->authenticationProof =
+ // H( H( U, daaCount, H(n0), joinSession->nonceEncrypted))
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ // enlarge capitalU to 256 (TPM_DAA_SIZE_issuerModulus)
+ // allocation
+ capitalUPrime = bi_set_as_nbin( joinSession->capitalUprimeLength, joinSession->capitalUprime);
+ capitalUPrime_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus);
+ if (capitalUPrime_bytes == NULL) {
+ LogError("malloc of %d bytes failed", TPM_DAA_SIZE_issuerModulus);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_byte_array( capitalUPrime_bytes, TPM_DAA_SIZE_issuerModulus, capitalUPrime);
+ EVP_DigestUpdate(&mdctx, capitalUPrime_bytes, TPM_DAA_SIZE_issuerModulus);
+ bi_free_ptr( capitalUPrime);
+ daaCount = htonl( joinSession->daaCounter);
+ EVP_DigestUpdate(&mdctx, &daaCount, sizeof(UINT32));
+ EVP_DigestUpdate(&mdctx, digest_n0, digest_n0Length);
+ contextHashLength = EVP_MD_CTX_size(&mdctx);
+ contextHash = (BYTE *)malloc( contextHashLength);
+ if (contextHash == NULL) {
+ LogError("malloc of %d bytes failed", contextHashLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ EVP_DigestFinal(&mdctx, contextHash, NULL);
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ LogDebug("PK(0).n=%s", dump_byte_array( TPM_DAA_SIZE_issuerModulus, modulus_N0_bytes));
+ LogDebug("digestN0h=%s", dump_byte_array( digest_n0Length, digest_n0));
+ LogDebug("UPrime=%s", dump_byte_array( TPM_DAA_SIZE_issuerModulus, capitalUPrime_bytes));
+ LogDebug("daaCount=%4x", daaCount);
+
+ LogDebug("contextHash[%d]=%s", contextHashLength, dump_byte_array( contextHashLength, contextHash));
+ EVP_DigestUpdate(&mdctx, contextHash, contextHashLength);
+ EVP_DigestUpdate(&mdctx, joinSession->nonceEncrypted, joinSession->nonceEncryptedLength);
+ hashLength = EVP_MD_CTX_size(&mdctx);
+ hash = (BYTE *)malloc( hashLength);
+ if (hash == NULL) {
+ LogError("malloc of %d bytes failed", hashLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ EVP_DigestFinal(&mdctx, hash, NULL);
+ if( credentialRequest->authenticationProofLength != hashLength ||
+ memcmp( credentialRequest->authenticationProof, hash, hashLength) != 0) {
+ LogError("Verification of authenticationProof failed - Step 2.b");
+ LogError("credentialRequest->authenticationProof[%d]=%s",
+ credentialRequest->authenticationProofLength,
+ dump_byte_array( credentialRequest->authenticationProofLength,
+ credentialRequest->authenticationProof));
+ LogError("internal cByte[%d]=%s",
+ hashLength,
+ dump_byte_array( hashLength, hash));
+ result = TSS_E_DAA_AUTHENTICATION_ERROR;
+ goto close;
+ } else
+ LogDebug("verify_authenticity Done:%s",
+ dump_byte_array( hashLength, hash));
+close:
+ free( contextHash);
+ free( digest_n0);
+ free( capitalUPrime_bytes);
+ free( hash);
+ return result;
+}
+
+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) { // out allocation
+ EVP_MD_CTX mdctx;
+ BYTE *encoded_pk;
+ BYTE *byte_array;
+ UINT32 encoded_pkLength;
+
+ byte_array = (BYTE *)malloc( DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8); // allocation
+ if (byte_array == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ encoded_pk = encoded_DAA_PK_internal( &encoded_pkLength, pk_intern);
+ EVP_DigestUpdate(&mdctx, encoded_pk, encoded_pkLength);
+ LogDebug( "issuerPk: %s", dump_byte_array( encoded_pkLength, encoded_pk));
+ bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8, v_prime_prime);
+ EVP_DigestUpdate(&mdctx, byte_array, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8);
+ LogDebug( "vPrimePrime: %s",
+ dump_byte_array( DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8, byte_array));
+ free( byte_array);
+ // allocation
+ byte_array = (BYTE *)malloc( DAA_PARAM_SIZE_RSA_MODULUS / 8);
+ if (byte_array == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_RSA_MODULUS / 8);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8, capitalA);
+ EVP_DigestUpdate(&mdctx, byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8);
+ LogDebug( "capitalA: %s", dump_byte_array( DAA_PARAM_SIZE_RSA_MODULUS / 8, byte_array));
+ bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8, capital_Atilde);
+ EVP_DigestUpdate(&mdctx, byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8);
+ LogDebug( "capital_Atilde: %s",
+ dump_byte_array( DAA_PARAM_SIZE_RSA_MODULUS / 8, byte_array));
+ EVP_DigestUpdate(&mdctx, nonceReceiver, nonceReceiverLength);
+ LogDebug( "nonceReceiver: %s",
+ dump_byte_array( nonceReceiverLength, nonceReceiver));
+ *c_primeLength = EVP_MD_CTX_size(&mdctx);
+ *c_prime = (BYTE *)malloc( *c_primeLength);
+ if (*c_prime == NULL) {
+ LogError("malloc of %d bytes failed", *c_primeLength);
+ free( byte_array);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ LogDebug( "c_prime: %s", dump_byte_array( *c_primeLength, *c_prime));
+ EVP_DigestFinal(&mdctx, *c_prime, NULL);
+ free( byte_array);
+ return TSS_SUCCESS;
+}
+
+// inspired by computeCredentialProof (IssuerTransaction.java)
+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, // out
+ bi_ptr *s_e // out
+) {
+ bi_ptr random_E = bi_new_ptr();
+ bi_ptr capital_Atilde = bi_new_ptr();
+ BYTE *c_prime_bytes;
+ UINT32 c_primeLength;
+
+ bi_urandom( random_E, bi_length( productPQprime) + DAA_PARAM_SAFETY_MARGIN * 8);
+ bi_mod( random_E, random_E, productPQprime);
+ bi_inc( random_E);
+ bi_mod_exp( capital_Atilde, fraction_A, random_E, pk_intern->modulus);
+ compute_join_challenge_issuer( pk_intern,
+ v_prime_prime,
+ capital_A,
+ capital_Atilde,
+ noncePlatformLength,
+ noncePlatform,
+ &c_primeLength,
+ &c_prime_bytes); // allocation
+ *c_prime = bi_set_as_nbin( c_primeLength, c_prime_bytes); // allocation
+ *s_e = bi_new_ptr();
+ bi_mul( *s_e, *c_prime, eInverse);
+ bi_mod( *s_e, *s_e, productPQprime);
+ bi_sub( *s_e, random_E, *s_e);
+ bi_mod( *s_e, *s_e, productPQprime);
+ bi_free_ptr( capital_Atilde);
+ bi_free_ptr( random_E);
+ free( c_prime_bytes);
+ return TSS_SUCCESS;
+}
+
+// from IssuerTransaction.java (joinStep2)
+// stacks: TCGApplication.java (retrieveDAACredential) -> Issuer.java(issueCredential)
+TSPICALL Tspi_DAA_IssueCredential_internal
+(
+ TSS_HDAA hDAA, // in
+ UINT32 attributesIssuerLength, // in
+ BYTE** attributesIssuer, // in
+ TSS_DAA_CREDENTIAL_REQUEST credentialRequest, // in
+ TSS_DAA_JOIN_ISSUER_SESSION joinSession, // in
+ TSS_DAA_CRED_ISSUER* credIssuer // out
+) {
+ TSS_RESULT result = TSS_SUCCESS;
+ TCS_CONTEXT_HANDLE tcsContext;
+ bi_ptr capitalU_hat_prime = NULL;
+ bi_ptr tmp1;
+ bi_ptr tmp2;
+ bi_ptr sa_i;
+ bi_ptr capitalU_prime = NULL;
+ bi_ptr c = NULL;
+ bi_ptr n = NULL;
+ bi_ptr sf0 = NULL;
+ bi_ptr sf1 = NULL;
+ bi_ptr sv_prime = NULL;
+ bi_ptr capitalR0 = NULL;
+ bi_ptr capitalR1 = NULL;
+ bi_ptr capitalS = NULL;
+ bi_ptr capitalU = NULL;
+ bi_ptr capitalU_hat = NULL;
+ bi_ptr capitalN_hat_i = NULL;
+ bi_ptr exp = NULL;
+ bi_ptr product_attr_receiver = NULL;
+ bi_ptr product_attr_issuer = NULL;
+ bi_ptr sv_tilde_prime = NULL;
+ bi_ptr capital_ni = NULL;
+ bi_ptr v_hat = NULL;
+ bi_ptr fraction_A = NULL;
+ bi_ptr capitalA = NULL;
+ bi_ptr e = NULL;
+ bi_ptr eInverse = NULL;
+ bi_ptr v_prime_prime = NULL;
+ bi_ptr c_prime = NULL;
+ bi_ptr s_e = NULL;
+ bi_ptr zeta = NULL;
+ TSS_DAA_PK *daa_pk_extern;
+ TSS_DAA_PK_internal *pk_intern;
+ TSS_DAA_PRIVATE_KEY *private_key;
+ UINT32 i, chLength, challengeLength, length, interval;
+ EVP_MD_CTX mdctx;
+ BYTE *ch = NULL, *challenge = NULL;
+
+ tmp1 = bi_new_ptr();
+ tmp2 = bi_new_ptr();
+ if( tmp1 == NULL || tmp2 == NULL) {
+ LogError("malloc of BI <%s> failed", "tmp1, tmp2");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS) goto close;
+ // 1 TODO Check the TPM rogue list
+
+ // 2 verify the authentication proof of the TPM
+ result = verify_authentificity(&credentialRequest, &joinSession);
+ if( result != TSS_SUCCESS) goto close;
+ daa_pk_extern = (TSS_DAA_PK *)(((TSS_DAA_KEY_PAIR *)joinSession.issuerKeyPair)->public_key);
+ pk_intern = e_2_i_TSS_DAA_PK( daa_pk_extern);
+ n = bi_set_as_nbin( daa_pk_extern->modulusLength,
+ daa_pk_extern->modulus); // allocation
+ if( n == NULL) {
+ LogError("malloc of BI <%s> failed", "n");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capitalR0 = bi_set_as_nbin( daa_pk_extern->capitalR0Length,
+ daa_pk_extern->capitalR0); // allocation
+ if( capitalR0 == NULL) {
+ LogError("malloc of BI <%s> failed", "capitalR0");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capitalR1 = bi_set_as_nbin( daa_pk_extern->capitalR1Length,
+ daa_pk_extern->capitalR1); // allocation
+ if( capitalR1 == NULL) {
+ LogError("malloc of BI <%s> failed", "capitalR1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capitalS = bi_set_as_nbin( daa_pk_extern->capitalSLength,
+ daa_pk_extern->capitalS); // allocation
+ if( capitalS == NULL) {
+ LogError("malloc of BI <%s> failed", "capitalS");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capitalU = bi_set_as_nbin( credentialRequest.capitalULength,
+ credentialRequest.capitalU); // allocation
+ if( capitalU == NULL) {
+ LogError("malloc of BI <%s> failed", "capitalU");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ sv_tilde_prime = bi_set_as_nbin( credentialRequest.sVtildePrimeLength,
+ credentialRequest.sVtildePrime); // allocation
+ if( sv_tilde_prime == NULL) {
+ LogError("malloc of BI <%s> failed", "sv_tilde_prime");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capital_ni = bi_set_as_nbin( credentialRequest.capitalNiLength,
+ credentialRequest.capitalNi); // allocation
+ if( capital_ni == NULL) {
+ LogError("malloc of BI <%s> failed", "capital_ni");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // 3 Verify the correctness proof of the credential request
+ // 3.a TODO commitments
+
+ // 3.b
+ capitalU_prime = bi_set_as_nbin( joinSession.capitalUprimeLength,
+ joinSession.capitalUprime); // allocation
+ if( capitalU_prime == NULL) {
+ LogError("malloc of BI <%s> failed", "capitalU_prime");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ sf0 = bi_set_as_nbin( credentialRequest.sF0Length,
+ credentialRequest.sF0); // allocation
+ if( sf0 == NULL) {
+ LogError("malloc of BI <%s> failed", "sf0");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ sf1 = bi_set_as_nbin( credentialRequest.sF1Length,
+ credentialRequest.sF1); // allocation
+ if( sf1 == NULL) {
+ LogError("malloc of BI <%s> failed", "sf1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ sv_prime = bi_set_as_nbin( credentialRequest.sVprimeLength,
+ credentialRequest.sVprime); // allocation
+ if( sv_prime == NULL) {
+ LogError("malloc of BI <%s> failed", "sv_prime");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ c = bi_set_as_nbin( credentialRequest.challengeLength,
+ credentialRequest.challenge); // allocation
+ if( c == NULL) {
+ LogError("malloc of BI <%s> failed", "c");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capitalU_hat_prime = bi_new_ptr();// allocation
+ if( capitalU_hat_prime == NULL) {
+ LogError("malloc of BI <%s> failed", "c");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // capitalU_hat_prime = capitalU_prime ~% n
+ bi_invert_mod( capitalU_hat_prime, capitalU_prime, n);
+ // capitalU_hat_prime = ( capitalU_hat_prime ^ c ) % n
+ bi_mod_exp( capitalU_hat_prime, capitalU_hat_prime, c, n);
+ // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalR0 ^ sf0)) % n
+ bi_mod_exp( tmp1, capitalR0, sf0, n);
+ bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1);
+ bi_mod( capitalU_hat_prime, capitalU_hat_prime, n);
+ // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalR1 ^ sf1)) % n
+ bi_mod_exp( tmp1, capitalR1, sf1, n);
+ bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1);
+ bi_mod( capitalU_hat_prime, capitalU_hat_prime, n);
+ // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalS ^ sv_prime)) % n
+ bi_mod_exp( tmp1, capitalS, sv_prime, n);
+ bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1);
+ bi_mod( capitalU_hat_prime, capitalU_hat_prime, n);
+ // verify blinded encoded attributes of the Receiver
+ product_attr_receiver = bi_new_ptr();
+ bi_set( product_attr_receiver, bi_1);
+ length = ( DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8;
+ for( i=0; i<credentialRequest.sALength; i++) {
+ sa_i = bi_set_as_nbin( length, credentialRequest.sA[i]); // allocation
+ if( sa_i == NULL) {
+ LogError("malloc of BI <%s> failed", "sa_i");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( tmp1, pk_intern->capitalRReceiver->array[i], sa_i, n);
+ bi_mul( product_attr_receiver, product_attr_receiver, tmp1);
+ bi_mod( product_attr_receiver, product_attr_receiver, n);
+ bi_free_ptr( sa_i);
+ }
+ // tmp1 = ( 1 / capitalU ) % n
+ bi_invert_mod( tmp1, capitalU, n);
+ capitalU_hat = bi_new_ptr();
+ if( capitalU_hat == NULL) {
+ LogError("malloc of BI <%s> failed", "capitalU_hat");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mul( capitalU_hat, capitalU_prime, tmp1);
+ // capitalU_hat = capitalU_prime / capitalU
+ bi_mod( capitalU_hat, capitalU_hat, n);
+ // capital_Uhat = ( (capital_Uhat ^ c ) % n
+ bi_mod_exp( capitalU_hat, capitalU_hat, c, n);
+ // capital_Uhat = ( capital_Uhat * ( capitalS ^ sv_tilde_prime) % n ) % n
+ bi_mod_exp( tmp1, pk_intern->capitalS, sv_tilde_prime, n);
+ bi_mul( capitalU_hat, capitalU_hat, tmp1);
+ bi_mod( capitalU_hat, capitalU_hat, n);
+ bi_mul( capitalU_hat, capitalU_hat, product_attr_receiver);
+ bi_mod( capitalU_hat, capitalU_hat, n);
+ // capital_Nhat_i = (( capital_Ni ~% pk_intern->capitalGamma ) ^ c ) % pk_intern->capitalGamma
+ capitalN_hat_i = bi_new_ptr();
+ bi_invert_mod( capitalN_hat_i, capital_ni, pk_intern->capitalGamma);
+ bi_mod_exp( capitalN_hat_i, capitalN_hat_i, c, pk_intern->capitalGamma);
+ // exp = sf1 << (DAA_PARAM_SIZE_F_I) + sf0
+ exp = bi_new_ptr();
+ if( exp == NULL) {
+ LogError("malloc of BI <%s> failed", "exp");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_shift_left( exp, sf1, DAA_PARAM_SIZE_F_I);
+ bi_add( exp, exp, sf0);
+ zeta = compute_zeta( pk_intern->issuerBaseNameLength,
+ pk_intern->issuerBaseName,
+ pk_intern);
+ // capital_Nhat_i = ( capital_Nhat_i *
+ // ( ( issuer.zeta ^ exp) % pk->capitalGamma) ) % pk->capitalGamma
+ bi_mod_exp( tmp1, zeta, exp, pk_intern->capitalGamma);
+ bi_mul( capitalN_hat_i, capitalN_hat_i, tmp1);
+ bi_mod( capitalN_hat_i, capitalN_hat_i, pk_intern->capitalGamma);
+
+ LogDebug("calculation Uhat: capitalS:%s\n", bi_2_hex_char( pk_intern->capitalS));
+ LogDebug("calculation Uhat: sv_tilde_prime:%s\n", bi_2_hex_char( sv_tilde_prime));
+ LogDebug("calculation Uhat: n:%s\n", bi_2_hex_char( n));
+ LogDebug("calculation Uhat: product_attributes:%s\n", bi_2_hex_char( product_attr_receiver));
+ LogDebug("calculation NhatI: zeta:%s\n", bi_2_hex_char( zeta));
+ LogDebug("calculation NhatI: exp:%s\n", bi_2_hex_char( exp));
+ LogDebug("calculation NhatI: capitalGamma:%s\n", bi_2_hex_char( pk_intern->capitalGamma));
+ // calculate challenge
+ result = compute_join_challenge_host(hDAA,
+ pk_intern,
+ capitalU,
+ capitalU_prime,
+ capitalU_hat,
+ capitalU_hat_prime,
+ capital_ni,
+ capitalN_hat_i,
+ 0, // TODO: commitmentsProofLength
+ NULL, // TODO: commits
+ joinSession.nonceIssuerLength,
+ joinSession.nonceIssuer,
+ &chLength, // out
+ &ch); // out allocation
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("JoinChallengeHost: %s", dump_byte_array( chLength, ch));
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ EVP_DigestUpdate(&mdctx, ch, chLength);
+ challengeLength = EVP_MD_CTX_size( &mdctx);
+ challenge = (BYTE *)malloc( challengeLength);
+ if( challenge == NULL) {
+ LogError("malloc of %d bytes failed", challengeLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ EVP_DigestUpdate(&mdctx, credentialRequest.nonceTpm, credentialRequest.nonceTpmLength);
+ EVP_DigestFinal(&mdctx, challenge, NULL);
+ // checks
+ if( credentialRequest.challengeLength != challengeLength ||
+ memcmp( credentialRequest.challenge, challenge, challengeLength)!=0) {
+ LogError("Verification of c failed - Step 3.f.i");
+ LogError("credentialRequest.challenge[%d]=%s",
+ credentialRequest.challengeLength,
+ dump_byte_array( credentialRequest.challengeLength,
+ credentialRequest.challenge));
+ LogError("challenge[%d]=%s",
+ challengeLength,
+ dump_byte_array( challengeLength, challenge));
+ result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
+ goto close;
+ }
+ // + 1 because the result of ( rA(43 bits) + c(20 bits) * a(13 bits)) can
+ // shift 1 bit above the normal size (43 bits)
+ length = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 1;
+ if( bi_length( sf0) > (long)length) {
+ LogError( "Verification of sF0 failed - Step 3.f.ii");
+ LogError("\tsf0 bits length: %d expected maximum length:%d\n",
+ (int)bi_length( sf0), (int)length);
+ result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
+ goto close;
+ }
+ if( bi_length( sf1) > (long)length) {
+ LogError( "Verification of sF1 failed - Step 3.f.ii");
+ LogError("\tsf1 length: %d expected maximum length:%d\n",
+ (int)bi_length( sf1), (int)length);
+ result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
+ goto close;
+ }
+ // blinded attributes
+ length = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES;
+ for( i=0; i<credentialRequest.sALength; i++) {
+ sa_i = bi_set_as_nbin( ( length + 7) / 8, credentialRequest.sA[i]); // allocation
+ if( sa_i == NULL) {
+ LogError("malloc of BI <%s> failed", "sa_i");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ if( bi_length( sa_i) > (long)length) {
+ LogError("Verification of sA[%d] failed - Step 3.f.ii", i);
+ LogError("sA.length=%d length=%d", (int)bi_length( sa_i), length);
+ result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
+ goto close;
+ }
+ bi_free_ptr( sa_i);
+ if( result != TSS_SUCCESS) goto close;
+ }
+ length = DAA_PARAM_SIZE_RSA_MODULUS + 2 * DAA_PARAM_SAFETY_MARGIN +
+ DAA_PARAM_SIZE_MESSAGE_DIGEST;
+ if( bi_length( sv_prime) > (int)length) {
+ LogError("Verification of sVprime failed - Step 3.f.iii\n");
+ LogError("\tsv_prime bits length: %d expected maximum length:%d\n",
+ (int)bi_length( sv_prime), (int)length);
+ result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
+ goto close;
+ }
+ if( bi_nbin_size( sv_tilde_prime) > (int)length) {
+ LogError("Verification of sVtildePrime failed - Step 3.f.iii");
+ LogError("\tsv_tilde_prime bits length: %d expected maximum length:%d\n",
+ (int)bi_length( sv_tilde_prime), (int)length);
+ result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR;
+ goto close;
+ }
+ // compute credential
+ v_hat = bi_new_ptr();
+ if( v_hat == NULL) {
+ LogError("malloc of BI <%s> failed", "v_hat");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_urandom( v_hat, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE - 1);
+ length = DAA_PARAM_SIZE_EXPONENT_CERTIFICATE;
+ interval = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE;
+ e = bi_new_ptr();
+ if( e == NULL) {
+ LogError("malloc of BI <%s> failed", "e");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ compute_prime( e, length, interval);
+
+ // v'' = ( 1 << DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE) + v_hat
+ v_prime_prime = bi_new_ptr();
+ bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE - 1);
+ bi_add( v_prime_prime, tmp1, v_hat);
+
+ // fraction_A = (( pk->capitalS ^ v``) % n) * capitalU
+ fraction_A = bi_new_ptr();
+ if( fraction_A == NULL) {
+ LogError("malloc of BI <%s> failed", "fraction_A");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( fraction_A, pk_intern->capitalS, v_prime_prime, n);
+ bi_mul( fraction_A, fraction_A, capitalU);
+ bi_mod( fraction_A, fraction_A, n);
+
+ // encode attributes
+ bi_free_ptr( tmp1);
+ product_attr_issuer = bi_new_ptr();
+ if( product_attr_issuer == NULL) {
+ LogError("malloc of BI <%s> failed", "product_attr_issuer");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( product_attr_issuer, bi_1);
+ for( i=0; i< attributesIssuerLength; i++) {
+ tmp1 = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, attributesIssuer[i]); // allocation
+ bi_mod_exp( tmp2, pk_intern->capitalRIssuer->array[i], tmp1, n);
+ bi_mul( product_attr_issuer, product_attr_issuer, tmp2);
+ bi_mod( product_attr_issuer, product_attr_issuer, n);
+ bi_free_ptr( tmp1);
+ }
+ tmp1 = bi_new_ptr();
+ if( tmp1 == NULL) {
+ LogError("malloc of BI <%s> failed", "tmp1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mul( fraction_A, fraction_A, product_attr_issuer);
+ bi_mod( fraction_A, fraction_A, n);
+
+ bi_invert_mod( fraction_A, fraction_A, n);
+ bi_mul( fraction_A, fraction_A, pk_intern->capitalZ);
+ bi_mod( fraction_A, fraction_A, n);
+
+ private_key = (TSS_DAA_PRIVATE_KEY *)
+ (((TSS_DAA_KEY_PAIR *)joinSession.issuerKeyPair)->private_key);
+ bi_free_ptr( tmp2);
+ tmp2 = bi_set_as_nbin( private_key->productPQprimeLength,
+ private_key->productPQprime); // allocation
+ if( tmp2 == NULL) {
+ LogError("malloc of BI <%s> failed", "tmp2");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ eInverse = bi_new_ptr();
+ if( eInverse == NULL) {
+ LogError("malloc of BI <%s> failed", "eInverse");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_invert_mod( eInverse, e, tmp2);
+ capitalA = bi_new_ptr();
+ if( capitalA == NULL) {
+ LogError("malloc of BI <%s> failed", "capitalA");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug("fraction_A[%ld]=%s", bi_nbin_size( fraction_A), bi_2_hex_char( fraction_A));
+ LogDebug("eInverse[%ld]=%s", bi_nbin_size( eInverse), bi_2_hex_char( eInverse));
+ LogDebug("productPQprime[%ld]=%s", bi_nbin_size( tmp2), bi_2_hex_char( tmp2));
+ LogDebug("eInverse[%ld]=%s", bi_nbin_size( eInverse), bi_2_hex_char( eInverse));
+ LogDebug("e[%ld]=%s", bi_nbin_size( e), bi_2_hex_char( e));
+ LogDebug("n[%ld]=%s", bi_nbin_size( n), bi_2_hex_char( n));
+ bi_mod_exp( capitalA, fraction_A, eInverse, n);
+
+ compute_credential_proof( pk_intern,
+ capitalA,
+ fraction_A,
+ eInverse,
+ v_prime_prime,
+ tmp2, // productPQprime
+ credentialRequest.noncePlatformLength,
+ credentialRequest.noncePlatform,
+ &c_prime, // out: allocation
+ &s_e); // out: allocation
+ // populate credIssuer (TSS_DAA_CRED_ISSUER *)
+ credIssuer->capitalA = calloc_tspi( tcsContext, bi_nbin_size( capitalA));
+ if( credIssuer->capitalA == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( capitalA));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credIssuer->capitalALength), credIssuer->capitalA, capitalA);
+ credIssuer->e = calloc_tspi( tcsContext, bi_nbin_size( e));
+ if( credIssuer->e == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( e));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credIssuer->eLength), credIssuer->e, e);
+ credIssuer->vPrimePrime = calloc_tspi( tcsContext, bi_nbin_size( v_prime_prime));
+ if( credIssuer->vPrimePrime == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( v_prime_prime));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credIssuer->vPrimePrimeLength), credIssuer->vPrimePrime, v_prime_prime);
+ // attributes issuer
+ credIssuer->attributesIssuerLength = attributesIssuerLength;
+ credIssuer->attributesIssuer = calloc_tspi( tcsContext,
+ attributesIssuerLength * sizeof( BYTE *));
+ if( credIssuer->attributesIssuer == NULL) {
+ LogError("malloc of %d bytes failed", attributesIssuerLength * sizeof( BYTE *));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( i=0; i< attributesIssuerLength; i++) {
+ credIssuer->attributesIssuer[i] = calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8);
+ if( credIssuer->attributesIssuer[i] == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ memcpy( credIssuer->attributesIssuer[i], attributesIssuer[i], DAA_PARAM_SIZE_F_I / 8);
+ }
+ credIssuer->cPrime = calloc_tspi( tcsContext, bi_nbin_size( c_prime));
+ if( credIssuer->cPrime == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( c_prime));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credIssuer->cPrimeLength), credIssuer->cPrime, c_prime);
+ credIssuer->sE = calloc_tspi( tcsContext, bi_nbin_size( s_e));
+ if( credIssuer->sE == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( s_e));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credIssuer->sELength), credIssuer->sE, s_e);
+
+close:
+ //free_TSS_DAA_PK( daa_pk_extern);
+ if( ch != NULL) free( ch);
+ if( challenge != NULL) free( challenge);
+ FREE_BI( tmp1);
+ FREE_BI( tmp2);
+ FREE_BI( s_e);
+ FREE_BI( c_prime);
+ FREE_BI( capitalA);
+ FREE_BI( v_prime_prime);
+ FREE_BI( eInverse);
+ FREE_BI( e);
+ FREE_BI( fraction_A);
+ FREE_BI( v_hat);
+ FREE_BI( capital_ni);
+ FREE_BI( sv_tilde_prime);
+ FREE_BI( product_attr_receiver);
+ FREE_BI( product_attr_issuer);
+ FREE_BI( capitalU_hat_prime);
+ FREE_BI( capitalU_prime);
+ FREE_BI( sv_prime);
+ FREE_BI( exp);
+ FREE_BI( capitalN_hat_i);
+ FREE_BI( capitalU_hat);
+ FREE_BI( capitalU);
+ FREE_BI( capitalS);
+ FREE_BI( capitalR1);
+ FREE_BI( capitalR0);
+ FREE_BI( sf1);
+ FREE_BI( sf0);
+ FREE_BI( n);
+ FREE_BI( c);
+ FREE_BI( zeta);
+ return result;
+}
diff --git a/src/tspi/daa/daa_issuer/issuer_init.c b/src/tspi/daa/daa_issuer/issuer_init.c
new file mode 100644
index 0000000..788bb8d
--- /dev/null
+++ b/src/tspi/daa/daa_issuer/issuer_init.c
@@ -0,0 +1,142 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// for message digest
+#include <openssl/evp.h>
+
+#include <stdlib.h>
+#include "daa_structs.h"
+#include "daa_parameter.h"
+#include "trousers/tss.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include <trousers/trousers.h>
+#include <spi_utils.h>
+#include <obj.h>
+#include "tsplog.h"
+#include "tss/tcs.h"
+
+/*
+Verifies if the key is a valid endorsement key of a TPM. (TPM is good)
+return 0 if correct
+ */
+int verify_ek_and_daaCounter(
+ UINT32 endorsementLength,
+ BYTE *endorsementCredential,
+ UINT32 daaCounter
+) {
+ // TODO
+ return 0;
+}
+
+
+TSS_RESULT Tspi_DAA_IssueInit_internal(
+ TSS_HDAA hDAA, // in
+ TSS_HKEY issuerAuthPK, // in
+ TSS_HKEY issuerKeyPair, // in (TSS_DAA_KEY_PAIR *)
+ TSS_DAA_IDENTITY_PROOF identityProof, // in
+ UINT32 capitalUprimeLength, // in
+ BYTE* capitalUprime, // in
+ UINT32 daaCounter, // in
+ UINT32* nonceIssuerLength, // out
+ BYTE** nonceIssuer, // out
+ UINT32* authenticationChallengeLength, // out
+ BYTE** authenticationChallenge, // out
+ TSS_DAA_JOIN_ISSUER_SESSION* joinSession // out
+) {
+ TCS_CONTEXT_HANDLE tcsContext;
+ TSS_RESULT result;
+ BYTE *ne, *buffer;
+ bi_t random;
+ int length_ne;
+
+ if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS)
+ return result;
+ // 1 & 2 : verify EK (and associated credentials) of the platform
+ if( verify_ek_and_daaCounter( identityProof.endorsementLength,
+ identityProof.endorsementCredential, daaCounter) != 0) {
+ LogError("EK verification failed");
+ return TSS_E_INTERNAL_ERROR;
+ }
+
+ // 3 : choose a random nonce for the platform (ni)
+ bi_new( random);
+ bi_urandom( random, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8);
+ buffer = bi_2_nbin( nonceIssuerLength, random);
+ if( buffer == NULL) {
+ LogError("malloc of %d bytes failed", *nonceIssuerLength);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ *nonceIssuer = convert_alloc( tcsContext, *nonceIssuerLength, buffer);
+ if (*nonceIssuer == NULL) {
+ LogError("malloc of %d bytes failed", *nonceIssuerLength);
+ free( buffer);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+
+ LogDebug("nonce Issuer[%d:%d]:%s", DAA_PARAM_LENGTH_MESSAGE_DIGEST,
+ *nonceIssuerLength,
+ dump_byte_array( *nonceIssuerLength , *nonceIssuer));
+
+ // 4 : choose a random nonce ne and encrypt it under EK
+ bi_urandom( random, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8);
+ ne = convert_alloc( tcsContext, length_ne, bi_2_nbin( &length_ne, random));
+ if (ne == NULL) {
+ LogError("malloc of %d bytes failed", length_ne);
+ free( buffer);
+ free( nonceIssuer);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+
+ bi_free( random);
+ *authenticationChallenge = (BYTE *)calloc_tspi( tcsContext, 256); // 256: RSA size
+ if (*authenticationChallenge == NULL) {
+ LogError("malloc of %d bytes failed", 256);
+ free( buffer);
+ free( nonceIssuer);
+ free( ne);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ result = Trspi_RSA_Encrypt(
+ ne, // message to encrypt
+ length_ne, // length message to encrypt
+ *authenticationChallenge, // destination
+ authenticationChallengeLength, // length destination
+ identityProof.endorsementCredential, // public key
+ identityProof.endorsementLength); // public key size
+ if( result != TSS_SUCCESS) {
+ LogError("Can not encrypt the Authentication Challenge");
+ free( buffer);
+ free( nonceIssuer);
+ free( ne);
+ return TSS_E_INTERNAL_ERROR;
+ }
+ LogDebug("authenticationChallenge[%d:%d]:%s", DAA_PARAM_LENGTH_MESSAGE_DIGEST,
+ *authenticationChallengeLength,
+ dump_byte_array( *authenticationChallengeLength , *authenticationChallenge));
+
+ // 5 : save PK, PKDAA, (p', q'), U', daaCounter, ni, ne in joinSession
+ // EK is not a member of joinSession but is already saved in identityProof
+ joinSession->issuerAuthPK = issuerAuthPK;
+ joinSession->issuerKeyPair = issuerKeyPair;
+ memcpy( &(joinSession->identityProof), &identityProof, sizeof(TSS_DAA_IDENTITY_PROOF));
+ joinSession->capitalUprimeLength = capitalUprimeLength;
+ joinSession->capitalUprime = capitalUprime;
+ joinSession->daaCounter = daaCounter;
+ joinSession->nonceIssuerLength = *nonceIssuerLength;
+ joinSession->nonceIssuer = *nonceIssuer;
+ joinSession->nonceEncryptedLength = length_ne;
+ joinSession->nonceEncrypted = ne;
+ return result;
+}
diff --git a/src/tspi/daa/daa_issuer/issuer_setup.c b/src/tspi/daa/daa_issuer/issuer_setup.c
new file mode 100644
index 0000000..44e3679
--- /dev/null
+++ b/src/tspi/daa/daa_issuer/issuer_setup.c
@@ -0,0 +1,166 @@
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "trousers/tss.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include "obj.h"
+// #include "tcslog.h"
+#include "bi.h"
+#include "daa_parameter.h"
+#include "issuer.h"
+
+static char *DEFAULT_FILENAME = "issuer.txt";
+static char *DEFAULT_ISSUER = "IBM-Issuer";
+
+static const int DEFAULT_ISSUER_ATTRIBUTES = 2; // A1 A2
+static const int DEFAULT_RECEIVER_ATTRIBUTES = 3; // A3 A4 A5
+
+int print_usage(char *cmd) {
+ fprintf(stderr, "usage: %s\n", cmd);
+ fprintf(stderr, " \t-npa,\t--nb_platform_attr\tnumber of attributes that the\
+ Platform can choose and which will not be visible to the Issuer (default: %d)\n",
+ DEFAULT_ISSUER_ATTRIBUTES);
+ fprintf(stderr, " \t-nia,\t--nb_issuer_attr\tnumber of attributes that the issuer\
+ can choose and which will be visible to both the Platform and the Issuer(default: %d)\n",
+ DEFAULT_RECEIVER_ATTRIBUTES);
+ fprintf(stderr, " \t-if,\t--issuer_file\tthe file that will contain all key pair\
+ and proof to be used by the issuer (default: %s)\n",
+ DEFAULT_FILENAME);
+ fprintf(stderr, " \t-i,\t--issuer\tissuer identity (default: %s)\n",
+ DEFAULT_ISSUER);
+ return -1;
+}
+
+int main(int argc, char *argv[]) {
+ int nb_platform_attr = DEFAULT_ISSUER_ATTRIBUTES;
+ int nb_issuer_attr = DEFAULT_RECEIVER_ATTRIBUTES;
+ char *filename = DEFAULT_FILENAME;
+ char *issuer = DEFAULT_ISSUER;
+ int i;
+ char *param;
+ TSS_HCONTEXT hContext;
+ TSS_DAA_KEY_PAIR *key_pair;
+ TSS_DAA_PK_PROOF *public_keyproof;
+ TSS_RESULT result;
+ TSS_HDAA hDAA;
+ TSS_DAA_PK_PROOF_internal *public_keyproof_internal;
+ TSS_DAA_PK_internal *pk;
+ TSS_DAA_PRIVATE_KEY *private_key;
+ DAA_PRIVATE_KEY_internal *private_key_internal;
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof;
+
+ printf("Issuer Setup (%s:%s,%s)\n", argv[0], __DATE__, __TIME__);
+ i = 1;
+ while( i < argc) {
+ param = argv[ i];
+ if ( strcmp( param, "-if") == 0 || strcmp( param, "--issuer_file")) {
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ filename = argv[i];
+ } else if( strcmp( param, "-npa") == 0 || strcmp( param, "--nb_platform_attr")) {
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ nb_platform_attr = atoi( argv[i]);
+ } else if( strcmp( param, "-nia") == 0 || strcmp( param, "--nb_issuer_attr")) {
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ nb_issuer_attr = atoi(argv[i]);
+ } else if( strcmp( param, "-i") == 0 || strcmp( param, "--issuer")) {
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ issuer = argv[i];
+ } else {
+ fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param);
+ return print_usage( argv[0]);
+ }
+ i++;
+ }
+ bi_init( NULL);
+ // Create Context
+ printf("Create Context\n");
+ result = Tspi_Context_Create( &hContext );
+ if ( result != TSS_SUCCESS )
+ {
+ fprintf( stderr, "Tspi_Context_Create %d\n", result );
+ exit( result );
+ }
+
+ // Connect to Context
+ printf("Connect to the context\n");
+ result = Tspi_Context_Connect( hContext, NULL );
+ if ( result != TSS_SUCCESS )
+ {
+ fprintf( stderr, "Tspi_Context_Connect error:%d\n", result );
+ Tspi_Context_FreeMemory( hContext, NULL );
+ Tspi_Context_Close( hContext );
+ exit( result );
+ }
+ //Create Object
+ result = obj_daa_add( hContext, &hDAA);
+ if (result != TSS_SUCCESS) {
+ goto close;
+ }
+ result = Tspi_DAA_IssueSetup(
+ hDAA, // in
+ strlen( issuer), // in
+ (BYTE *)issuer, // in
+ nb_platform_attr, // in
+ nb_issuer_attr, // in
+ (TSS_HKEY *)&key_pair, // out
+ &public_keyproof); // out
+ if( result != TSS_SUCCESS) goto close;
+
+ // TSS_DAA_KEY_PAIR_internal *key_pair_internal = DAA_KEY_PAIR_2_internal( key_pair);
+ public_keyproof_internal = e_2_i_TSS_DAA_PK_PROOF( public_keyproof);
+ pk = e_2_i_TSS_DAA_PK( key_pair->public_key);
+ private_key = key_pair->private_key;
+ private_key_internal = e_2_i_TSS_DAA_PRIVATE_KEY( private_key);
+ key_pair_with_proof =
+ (KEY_PAIR_WITH_PROOF_internal *)malloc( sizeof(KEY_PAIR_WITH_PROOF_internal));
+ if( key_pair_with_proof == NULL) {
+ fprintf("malloc of %d bytes failed", sizeof(KEY_PAIR_WITH_PROOF_internal));
+ goto close;
+ }
+ key_pair_with_proof->pk = pk;
+ key_pair_with_proof->private_key = private_key_internal;
+ key_pair_with_proof->proof = public_keyproof_internal;
+
+ printf("Saving key pair with proof -> \'%s\'", filename);
+ FILE *file = fopen( filename, "w");
+ if( file == NULL) {
+ fprintf( stderr, "%s: Error when saving \'%s\': %s\n",
+ argv[0],
+ filename,
+ strerror( errno));
+ return -1;
+ }
+ if( save_KEY_PAIR_WITH_PROOF( file, key_pair_with_proof) != 0) {
+ fprintf( stderr, "%s: Error when saving \'%s\': %s\n",
+ argv[0],
+ filename,
+ strerror( errno));
+ return -1;
+ }
+ fclose( file);
+ printf("\nDone.\n");
+close:
+ obj_daa_remove( hDAA, hContext);
+ printf("Closing the context\n");
+ Tspi_Context_FreeMemory( hContext, NULL );
+ Tspi_Context_Close( hContext );
+ bi_release();
+ printf("Result: %d", result);
+ return result;
+}
diff --git a/src/tspi/daa/daa_issuer/key_correctness_proof.c b/src/tspi/daa/daa_issuer/key_correctness_proof.c
new file mode 100644
index 0000000..505e760
--- /dev/null
+++ b/src/tspi/daa/daa_issuer/key_correctness_proof.c
@@ -0,0 +1,516 @@
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// for little-big endian conversion
+#include <arpa/inet.h>
+// for message digest
+#include <openssl/evp.h>
+
+#include "bi.h"
+
+#include "daa_parameter.h"
+#include "list.h"
+#include "daa_structs.h"
+
+#include "issuer.h"
+
+//standard bit length extension to obtain a uniformly distributed number [0,element]
+static const int SAFETY_PARAM = 80;
+
+static bi_array_ptr get_generators( const TSS_DAA_PK_internal *pk) {
+ bi_array_ptr result = ALLOC_BI_ARRAY();
+ int i;
+
+ bi_new_array( result, 3 + pk->capitalY->length );
+ for(i = 0; i<result->length; i++) {
+ result->array[i] = pk->capitalS;
+ }
+ return result;
+}
+
+static bi_array_ptr get_verifiable_numbers( const TSS_DAA_PK_internal *pk) {
+ bi_array_ptr result = ALLOC_BI_ARRAY();
+ int i;
+
+ bi_new_array( result, 3 + pk->capitalY->length);
+ result->array[0] = pk->capitalZ;
+ result->array[1] = pk->capitalR0;
+ result->array[2] = pk->capitalR1;
+ // CAPITAL Y ( capitalRReceiver + capitalRIssuer)
+ for( i=0; i<pk->capitalY ->length; i++)
+ result->array[ 3+i] = pk->capitalY->array[i];
+ return result;
+}
+
+/* computes an array of random numbers in the range of [1,element] */
+void compute_random_numbers( bi_array_ptr result, int quantity, const bi_ptr element) {
+ int i=0;
+
+ for( i=0; i<quantity; i++) {
+ compute_random_number( result->array[i], element);
+ bi_inc( result->array[i]); // array[i]++
+ }
+}
+
+int test_bit( int pos, BYTE* array, int length) {
+ return (((int)array[ length - (pos / 8) - 1]) & (1 << (pos % 8))) != 0;
+}
+
+void toByteArray( BYTE *result, int length, bi_ptr bi, char *logMsg) {
+ LogDebug("-> toByteArray <%d> %s",(int)bi, logMsg);
+ LogDebug("lenghts <%d|%d>",length, (int)bi_nbin_size(bi));
+ bi_2_byte_array( result, length, bi);
+ LogDebug("<- toByteArray result=%s [<%d|%d>] ",
+ dump_byte_array( length, result),
+ length,
+ (int)bi_nbin_size(bi));
+}
+
+/*
+Compute the message digest used in the proof. (from DAA_Param, the digest
+algorithm is RSA, but this is not available in openssl, the successor of RSA is SHA1
+*/
+TSS_RESULT
+generateMessageDigest(BYTE *md_value,
+ int *md_len,
+ const TSS_DAA_PK_internal *pk,
+ bi_array_ptr *commitments,
+ const int commitments_size
+) {
+ EVP_MD_CTX mdctx;
+ const EVP_MD *md;
+ int i, j;
+ int length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
+ BYTE *array;
+
+ // 10000 to be sure, and this memory will be released quite quickly
+ array = (BYTE *)malloc( 10000);
+ if (array == NULL) {
+ LogError("malloc of %d bytes failed", 10000);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ OpenSSL_add_all_digests();
+ md = EVP_get_digestbyname( DAA_PARAM_MESSAGE_DIGEST_ALGORITHM);
+ EVP_MD_CTX_init(&mdctx);
+ EVP_DigestInit_ex(&mdctx, md, NULL);
+#ifdef DAA_DEBUG
+ fprintf(stderr, "modulus=%s\n", bi_2_hex_char( pk->modulus));
+#endif
+ toByteArray( array, length, pk->modulus,
+ "!! [generateMessageDigest modulus] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ toByteArray( array, length, pk->capitalS,
+ "!! [generateMessageDigest capitalS] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ // add capitalZ, capitalR0, capitalR1, capitalY
+ LogDebug("capitalZ capitalR0 capitalY");
+ toByteArray( array, length, pk->capitalZ,
+ "!! [generateMessageDigest capitalZ] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ toByteArray( array, length, pk->capitalR0,
+ "!! [generateMessageDigest capitalR0] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ toByteArray( array, length, pk->capitalR1,
+ "!! [generateMessageDigest capitalR1] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ // CAPITAL Y ( capitalRReceiver )
+ LogDebug("capitalRReceiver");
+ for( i=0; i<pk->capitalRReceiver->length; i++) {
+ toByteArray( array, length, pk->capitalRReceiver->array[i],
+ "!![generateMessageDigest capitalRReceiver] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ }
+ LogDebug("capitalRIssuer");
+ // CAPITAL Y ( capitalRIssuer)
+ for( i=0; i<pk->capitalRIssuer->length; i++) {
+ toByteArray( array, length, pk->capitalRIssuer->array[i],
+ "!![generateMessageDigest capitalRReceiver] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ }
+ LogDebug("commitments");
+ for( i=0; i<commitments_size; i++) {
+ for( j=0; j<commitments[i]->length; j++) {
+ toByteArray( array, length, commitments[i]->array[j],
+ "!! [generateMessageDigest commitments] current_size=%d length=%d\n");
+ EVP_DigestUpdate(&mdctx, array , length);
+ }
+ }
+ EVP_DigestFinal_ex(&mdctx, md_value, md_len);
+ EVP_MD_CTX_cleanup(&mdctx);
+ free( array);
+ return TSS_SUCCESS;
+}
+
+int is_range_correct( bi_ptr b, bi_ptr range) {
+ return bi_cmp( b, range) < 0 && bi_cmp( b, bi_0) >= 0;
+}
+
+/*
+Verifies if the parameters Z,R0,R1,RReceiver and RIssuer of the public key
+were correctly computed.
+pk: the public key, which one wants to verfy.
+*/
+TSS_RESULT
+is_pk_correct( TSS_DAA_PK_internal *public_key,
+ TSS_DAA_PK_PROOF_internal *proof,
+ int *isCorrect
+) {
+ int bit_size_message_digest = DAA_PARAM_SIZE_MESSAGE_DIGEST;
+ bi_ptr n = public_key->modulus;
+ int num_of_variables;
+ int i,j;
+ TSS_RESULT result = TSS_SUCCESS;
+ BYTE verifiable_challenge[EVP_MAX_MD_SIZE];
+ int length_challenge;
+ bi_array_ptr verifiable_numbers;
+ bi_array_ptr *verification_commitments = NULL;
+ bi_array_ptr generators = NULL;
+ bi_t tmp;
+ bi_t tmp1;
+#ifdef DAA_DEBUG
+ FILE *f;
+ bi_array_ptr *commitments;
+#endif
+
+ bi_new( tmp);
+ bi_new( tmp1);
+ *isCorrect = 0;
+#ifdef DAA_DEBUG
+ f=fopen("/tmp/commits", "r");
+ commitments = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables);
+ if (commitments == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( i=0; i<num_of_variables; i++) {
+ commitments[i] = ALLOC_BI_ARRAY();
+ BI_LOAD_ARRAY( commitments[i], f);
+ }
+ fclose(f);
+ DUMP_BI( n);
+#endif
+ LogDebug("STEP 1 ( Tspi_DAA_IssuerKeyVerification spec.)");
+ if( !bi_is_probable_prime( public_key->capitalGamma)) {
+ LogError( "pk->capitalGamma not prime\ncapitalGamma=\n%s",
+ bi_2_hex_char( public_key->capitalGamma));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( !bi_is_probable_prime( public_key->rho)) {
+ LogError( "pk->rho not prime\nrho=\n%s",
+ bi_2_hex_char( public_key->rho));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ // (capitalGamma - 1) % rho should be equal to 0
+ if( !bi_equals( bi_mod( tmp1, bi_sub( tmp1, public_key->capitalGamma, bi_1),
+ public_key->rho),
+ bi_0)) {
+ LogError( "(capitalGamma - 1) %% rho != 0\nActual value:\n%s",
+ bi_2_hex_char( tmp1));
+ result = TSS_E_BAD_PARAMETER;
+ }
+ // (gamma ^ rho) % capitalGamma should be equals to 1
+ if ( !bi_equals( bi_mod_exp( tmp1, public_key->gamma,
+ public_key->rho,
+ public_key->capitalGamma),
+ bi_1) ) {
+ LogError( "(gamma ^ rho) %% capitalGamma != 1\nActual value:\n%s",
+ bi_2_hex_char( tmp1));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ // (gamma ^ rho) % capitalGamma should be equal to 1
+ if ( !bi_equals( bi_mod_exp( tmp1,
+ public_key->gamma,
+ public_key->rho,
+ public_key->capitalGamma),
+ bi_1) ) {
+ LogError( "(gamma ^ rho) %% capitalGamma != 1\nActual value:\n%s",
+ bi_2_hex_char( tmp1));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ LogDebug("STEP 2 check whether all public key parameters have the required length");
+ if( bi_nbin_size( n) != DAA_PARAM_SIZE_RSA_MODULUS / 8) {
+ LogError( "size( n)[%ld] != DAA_PARAM_SIZE_RSA_MODULUS[%d]",
+ bi_nbin_size( n),
+ DAA_PARAM_SIZE_RSA_MODULUS / 8);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( bi_cmp( n, bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_RSA_MODULUS))
+ >= 0) {
+ LogError( "n[%ld] != DAA_PARAM_SIZE_RSA_MODULUS[%d]",
+ bi_nbin_size( n),
+ DAA_PARAM_SIZE_RSA_MODULUS);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( bi_cmp( n, bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_RSA_MODULUS - 1 ))
+ <= 0) {
+ LogError( "n[%ld] != DAA_PARAM_SIZE_RSA_MODULUS[%d]",
+ bi_nbin_size( n),
+ DAA_PARAM_SIZE_RSA_MODULUS);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ // rho
+ if( bi_nbin_size( public_key->rho) * 8 != DAA_PARAM_SIZE_RHO) {
+ LogError( "size( rho)[%ld] != DAA_PARAM_SIZE_RHO[%d]",
+ bi_nbin_size( public_key->rho) * 8,
+ DAA_PARAM_SIZE_RHO);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ // Gamma
+ if( bi_nbin_size( public_key->capitalGamma) * 8 != DAA_PARAM_SIZE_MODULUS_GAMMA) {
+ LogError( "size( rho)[%ld] != DAA_PARAM_SIZE_MODULUS_GAMMA[%d]",
+ bi_nbin_size( public_key->capitalGamma) * 8,
+ DAA_PARAM_SIZE_MODULUS_GAMMA);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( is_range_correct( public_key->capitalS, n) == 0) {
+ LogError( "range not correct( pk->capitalS)\ncapitalS=\n%s\nn=\n%s",
+ bi_2_hex_char( public_key->capitalS),
+ bi_2_hex_char( n));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( is_range_correct( public_key->capitalZ, n) == 0) {
+ LogError( "range not correct( pk->capitalZ)\ncapitalZ=\n%s\nn=\n%s",
+ bi_2_hex_char( public_key->capitalZ),
+ bi_2_hex_char( n));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( is_range_correct( public_key->capitalR0, n) == 0) {
+ LogError( "range not correct( pk->capitalR0)\ncapitalR0=\n%s\nn=\n%s",
+ bi_2_hex_char( public_key->capitalR0),
+ bi_2_hex_char( n));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( is_range_correct( public_key->capitalR1, n) == 0) {
+ LogError( "range not correct( pk->capitalR1)\ncapitalR1=\n%s\nn=\n%s",
+ bi_2_hex_char( public_key->capitalR1),
+ bi_2_hex_char( n));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ for( i=0; i<public_key->capitalY->length; i++) {
+ if( is_range_correct( public_key->capitalY->array[i], n) == 0) {
+ LogError( "range not correct(pk->capitalY[%d])\ncapitalY[%d]=\n%s\nn=\n%s",
+ i, i,
+ bi_2_hex_char( public_key->capitalY->array[i]),
+ bi_2_hex_char( n));
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ }
+ LogDebug("STEP 3 - compute verification commitments");
+ // only the array is allocated, but all refs are pointing to public_key numbers
+ generators = get_generators( public_key);
+ verifiable_numbers = get_verifiable_numbers( public_key);
+ num_of_variables = verifiable_numbers->length;
+ verification_commitments = (bi_array_ptr *)malloc( sizeof(bi_array_ptr)*num_of_variables);
+ if (verification_commitments == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(bi_array_ptr)*num_of_variables);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( i = 0; i<num_of_variables; i++) {
+ verification_commitments[i] = ALLOC_BI_ARRAY();
+ bi_new_array( verification_commitments[i], bit_size_message_digest);
+ for( j = 0; j<bit_size_message_digest; j++) {
+#ifdef DAA_DEBUG
+ printf( "[# i=%d j=%d test_bit:%d]",
+ i, j, test_bit( j, proof->challenge, proof->length_challenge));
+#endif
+ bi_mod_exp( verification_commitments[i]->array[j],
+ generators->array[i],
+ proof->response[i]->array[j], n);
+ if( test_bit( j, proof->challenge, proof->length_challenge)) {
+ bi_mul( verification_commitments[i]->array[j],
+ verification_commitments[i]->array[j],
+ verifiable_numbers->array[i]);
+#ifdef DAA_DEBUG
+ DUMP_BI( verification_commitments[i]->array[j]);
+#endif
+ bi_mod( verification_commitments[i]->array[j],
+ verification_commitments[i]->array[j],
+ n);
+ }
+#ifdef DAA_DEBUG
+ if( commitments != NULL &&
+ bi_equals( verification_commitments[i]->array[j],
+ commitments[i]->array[j]) ==0) {
+ LogError( "!! ERROR i=%d j=%d\n", i, j);
+ DUMP_BI( commitments[i]->array[j]);
+ DUMP_BI( verification_commitments[i]->array[j]);
+ DUMP_BI( generators->array[i]);
+ DUMP_BI( proof->response[i]->array[j]);
+ DUMP_BI( verifiable_numbers->array[i]);
+ }
+ printf( "o"); fflush( stdout);
+#endif
+ }
+ }
+ // STEP 3 - d
+ generateMessageDigest( verifiable_challenge,
+ &length_challenge,
+ public_key,
+ verification_commitments,
+ num_of_variables);
+ LogDebug("verifiable challenge=%s",
+ dump_byte_array( length_challenge, verifiable_challenge));
+ LogDebug(" challenge=%s",
+ dump_byte_array( proof->length_challenge, proof->challenge));
+ if( length_challenge != proof->length_challenge) {
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ for( i=0; i<length_challenge; i++) {
+ if( verifiable_challenge[i] != proof->challenge[i]) {
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ }
+ *isCorrect = ( memcmp( verifiable_challenge, proof->challenge, length_challenge) == 0);
+close:
+ if( verification_commitments != NULL) {
+ for( i = 0; i<num_of_variables; i++) {
+ bi_free_array( verification_commitments[i]);
+ }
+ free( verification_commitments);
+ }
+ if( generators != NULL) free( generators);
+ bi_free( tmp1);
+ bi_free( tmp);
+ return result;
+}
+
+
+TSS_DAA_PK_PROOF_internal *generate_proof(const bi_ptr product_PQ_prime,
+ const TSS_DAA_PK_internal *public_key,
+ const bi_ptr xz,
+ const bi_ptr x0,
+ const bi_ptr x1,
+ bi_array_ptr x
+) {
+ int i, j;
+ bi_array_ptr generators = get_generators( public_key);
+ bi_ptr n = public_key->modulus;
+ int num_of_variables;
+ int bit_size_message_digest = DAA_PARAM_SIZE_MESSAGE_DIGEST;
+ bi_array_ptr *xTildes = NULL;
+ BYTE *challenge_param;
+
+ bi_array_ptr exponents = ALLOC_BI_ARRAY();
+ bi_new_array2( exponents, 3 + x->length);
+ exponents->array[0] = xz; exponents->array[1] = x0; exponents->array[2] = x1;
+ bi_copy_array( x, 0, exponents, 3, x->length);
+ num_of_variables = exponents->length;
+ LogDebug("Step a - choose random numbers");
+ LogDebug("\nchoose random numbers\n");
+ xTildes = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables);
+ if (xTildes == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables);
+ return NULL;
+ }
+ for( i=0; i<num_of_variables; i++) {
+#ifdef DAA_DEBUG
+ printf("*");
+ fflush(stdout);
+#endif
+ xTildes[i] = ALLOC_BI_ARRAY();
+ bi_new_array( xTildes[i], bit_size_message_digest);
+ compute_random_numbers( xTildes[i], bit_size_message_digest, product_PQ_prime);
+ }
+ // Compute commitments
+ LogDebug("\ncompute commitments");
+ bi_array_ptr *commitments =
+ (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables);
+ if (commitments == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables);
+ return NULL;
+ }
+ for( i=0; i<num_of_variables; i++) {
+ commitments[i] = ALLOC_BI_ARRAY();
+ bi_new_array( commitments[i], bit_size_message_digest);
+ for( j=0; j<bit_size_message_digest; j++) {
+#ifdef DAA_DEBUG
+ printf("#");
+ fflush(stdout);
+#endif
+ bi_mod_exp( commitments[i]->array[j],
+ generators->array[i],
+ xTildes[i]->array[j],
+ n);
+ }
+ }
+#ifdef DAA_DEBUG
+ FILE *f=fopen("/tmp/commits", "w");
+ for( i=0; i<num_of_variables; i++) {
+ BI_SAVE_ARRAY( commitments[i], f);
+ }
+ fclose(f);
+#endif
+ LogDebug("Step b: compute challenge (message digest)");
+ BYTE challenge[EVP_MAX_MD_SIZE];
+ int length_challenge;
+ generateMessageDigest( challenge,
+ &length_challenge,
+ public_key,
+ commitments,
+ num_of_variables);
+ // STEP c - compute response
+ LogDebug("Step c: compute response\n");
+ bi_array_ptr *response = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables);
+ if (response == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables);
+ return NULL;
+ }
+ for( i=0; i<num_of_variables; i++) {
+ response[i] = ALLOC_BI_ARRAY();
+ bi_new_array( response[i], bit_size_message_digest);
+ for( j=0; j<bit_size_message_digest; j++) {
+ if( test_bit( j, challenge, length_challenge)) {
+ bi_sub( response[i]->array[j],
+ xTildes[i]->array[j],
+ exponents->array[i]);
+ } else {
+ bi_set( response[i]->array[j],
+ xTildes[i]->array[j]);
+ }
+ bi_mod( response[i]->array[j], response[i]->array[j], product_PQ_prime);
+#ifdef DAA_DEBUG
+ printf("#");
+ fflush(stdout);
+#endif
+ }
+ }
+ challenge_param = (BYTE *)malloc( length_challenge);
+ if (challenge_param == NULL) {
+ LogError("malloc of %d bytes failed", length_challenge);
+ return NULL;
+ }
+ memcpy( challenge_param, challenge, length_challenge);
+
+ return create_DAA_PK_PROOF( challenge_param,
+ length_challenge,
+ response,
+ num_of_variables);
+}
diff --git a/src/tspi/daa/daa_issuer/key_verification.c b/src/tspi/daa/daa_issuer/key_verification.c
new file mode 100644
index 0000000..d7584f0
--- /dev/null
+++ b/src/tspi/daa/daa_issuer/key_verification.c
@@ -0,0 +1,147 @@
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <trousers/tss.h>
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include "obj.h"
+#include "issuer.h"
+
+static char *DEFAULT_FILENAME = "issuer.txt";
+
+//static TSS_HCONTEXT _hContext;
+
+static void *intern_alloc( size_t size, TSS_HOBJECT param_alloc) {
+ // void *ret = calloc_tspi( , size);
+ void *ret = malloc( size);
+ LogDebug("[intern_alloc (%d)] -> %d", (int)size, (int)ret);
+ return ret;
+}
+
+void isCorrect( TSS_HDAA hDAA,
+ TSS_DAA_PK_internal *pk_internal,
+ TSS_DAA_PK_PROOF_internal *proof_internal)
+{
+ TSS_BOOL isCorrect;
+ TSS_RESULT result;
+ TSS_DAA_PK *pk;
+ TSS_DAA_PK_PROOF *pk_proof;
+
+ pk = i_2_e_TSS_DAA_PK( pk_internal, &intern_alloc, (TSS_HOBJECT)NULL);
+ pk_proof = i_2_e_TSS_DAA_PK_PROOF( proof_internal,
+ &intern_alloc,
+ (TSS_HOBJECT)NULL);
+ result = Tspi_DAA_IssuerKeyVerification( hDAA,
+ (TSS_HKEY)pk,
+ pk_proof,
+ &isCorrect);
+ if ( result != TSS_SUCCESS ) {
+ fprintf( stderr, "Tspi_DAA_IssuerKeyVerification error: %d\n", result );
+ }
+ free_TSS_DAA_PK( pk);
+ printf("isCorrect=%d\n", isCorrect);
+}
+
+int print_usage(char *cmd) {
+ fprintf(stderr, "usage: %s\n", cmd);
+ fprintf(stderr, "\t-if,\t--issuer_file\tthe file that will contain\
+ all key pair and proof to be used by the issuer (default: %s)\n", DEFAULT_FILENAME);
+ return -1;
+}
+
+int main(int argc, char *argv[]) {
+ char *filename = DEFAULT_FILENAME;
+ int i=1;
+ char *param;
+ TSS_RESULT result;
+ TSS_HCONTEXT hContext;
+ TSS_HDAA hDAA;
+ FILE *file;
+
+// foreground = 1; // for debug
+ printf("Key Verification (%s:%s,%s)\n", argv[0], __DATE__, __TIME__);
+ while( i < argc) {
+ param = argv[ i];
+ if( strcmp( param, "-if") == 0 || strcmp( param, "--issuer_file")) {
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ filename = argv[i];
+ } else {
+ fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param);
+ return print_usage( argv[0]);
+ }
+ i++;
+ }
+ bi_init( NULL);
+ printf("Loading issuer info (keypair & proof) -> \'%s\'", filename);
+ file = fopen( filename, "r");
+ if( file == NULL) {
+ fprintf( stderr,
+ "%s: Error when opening \'%s\': %s\n",
+ argv[0],
+ filename,
+ strerror( errno));
+ return -1;
+ }
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof = load_KEY_PAIR_WITH_PROOF( file);
+ if( key_pair_with_proof == NULL) {
+ fprintf( stderr,
+ "%s: Error when reading \'%s\': %s\n",
+ argv[0],
+ filename,
+ strerror( errno));
+ return -1;
+ }
+ fclose( file);
+
+ // Create Context
+ printf("\nCreate Context\n");
+ result = Tspi_Context_Create( &hContext );
+ if ( result != TSS_SUCCESS )
+ {
+ fprintf( stderr, "Tspi_Context_Create %d\n", result );
+ exit( result );
+ }
+
+ // Connect to Context
+ printf("\nConnect to the context\n");
+ result = Tspi_Context_Connect( hContext, NULL );
+ if ( result != TSS_SUCCESS )
+ {
+ fprintf( stderr, "Tspi_Context_Connect error:%d\n", result );
+ Tspi_Context_FreeMemory( hContext, NULL );
+ Tspi_Context_Close( hContext );
+ exit( result );
+ }
+
+ //TODO save key in the persistent store
+ // result = ps_write_key( fd, )
+
+ //Create Object
+ result = obj_daa_add( hContext, &hDAA);
+ if (result != TSS_SUCCESS) {
+ LogError("Tspi_Context_CreateObject:%d", result);
+ Tspi_Context_Close(hContext);
+ LogError("issuer_setup: %s", err_string(result));
+ exit(result);
+ }
+
+ // TSS_HDAA, TSS_HKEY, TSS_DAA_PK_PROOF, TSS_BOOL*
+ isCorrect( hDAA, key_pair_with_proof->pk, key_pair_with_proof->proof);
+ obj_daa_remove( hDAA, hContext);
+ printf("\nClosing the context\n");
+ Tspi_Context_FreeMemory( hContext, NULL );
+ Tspi_Context_Close( hContext );
+ exit( 0 );
+}
diff --git a/src/tspi/daa/daa_issuer/keypair_generator.c b/src/tspi/daa/daa_issuer/keypair_generator.c
new file mode 100644
index 0000000..9a67254
--- /dev/null
+++ b/src/tspi/daa/daa_issuer/keypair_generator.c
@@ -0,0 +1,397 @@
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "bi.h"
+#include "list.h"
+#include "daa_structs.h"
+#include "daa_parameter.h"
+#include "issuer.h"
+
+static const int ELEMENT = 0;
+static const int EXPONENT = 1;
+
+extern void prime_init();
+extern void compute_safe_prime(bi_ptr result, int bit_length, int prime_certainty);
+
+bi_ptr
+compute_random_number_star( bi_ptr result, const bi_ptr element)
+{
+ bi_t bi_tmp;
+
+ bi_new(bi_tmp);
+ do {
+ compute_random_number(result, element);
+ } while (!bi_equals_si(bi_gcd(bi_tmp, result, element), 1));
+
+ bi_free(bi_tmp);
+
+ return result;
+}
+
+/* Compute a generator of the group of quadratic residue modulo n. The
+ * generator will not be part of the subgroup of size 2.
+ * n: modulus */
+void
+compute_generator_quadratic_residue(bi_t qr, bi_t n)
+{
+ bi_t bi_tmp, bi_tmp1;
+
+ bi_new(bi_tmp);
+ bi_new(bi_tmp1);
+
+ do {
+ compute_random_number(qr, n);
+ // qr = (qr ^ bi_2) % n
+ bi_mod_exp(qr, qr, bi_2, n);
+ } while (bi_cmp_si(qr, 1) == 0 ||
+ bi_cmp_si(bi_gcd(bi_tmp, n, bi_sub_si(bi_tmp1, qr, 1)), 1) != 0);
+
+ bi_free(bi_tmp);
+ bi_free(bi_tmp1);
+}
+
+void
+compute_group_element(bi_ptr result[],
+ bi_ptr generator,
+ bi_ptr product_PQprime,
+ bi_ptr n)
+{
+ bi_t bi_tmp;
+
+ bi_new(bi_tmp);
+ compute_random_number(bi_tmp, product_PQprime);
+
+ // bi_tmp++
+ bi_inc(bi_tmp);
+
+ // result[ELEMENT] := (generator ^ bi_tmp) mod n
+ bi_mod_exp(result[ELEMENT], generator, bi_tmp, n);
+ bi_set(result[EXPONENT], bi_tmp);
+ bi_free(bi_tmp);
+}
+
+
+TSS_RESULT
+generate_key_pair(UINT32 num_attributes_issuer,
+ UINT32 num_attributes_receiver,
+ UINT32 base_nameLength,
+ BYTE* base_name,
+ KEY_PAIR_WITH_PROOF_internal** key_pair_with_proof)
+{
+ TSS_RESULT result = TSS_SUCCESS;
+ int length_mod = DAA_PARAM_SIZE_RSA_MODULUS;
+ int length;
+ int i;
+ TSS_DAA_PK_internal *public_key = NULL;
+ BYTE *buffer = NULL;
+ bi_ptr pPrime = NULL;
+ bi_ptr qPrime = NULL;
+ bi_ptr n = NULL;
+ bi_ptr p = NULL;
+ bi_ptr q = NULL;
+ bi_ptr capital_s = NULL;
+ bi_ptr capital_z = NULL;
+ bi_ptr product_PQprime = NULL;
+ bi_ptr pair[2] = {NULL, NULL};
+ bi_ptr xz = NULL;
+ bi_ptr capital_r0 = NULL;
+ bi_ptr x0 = NULL;
+ bi_ptr capital_r1 = NULL;
+ bi_ptr x1 = NULL;
+ bi_array_ptr x = NULL;
+ bi_array_ptr capital_r = NULL;
+ bi_array_ptr capitalRReceiver = NULL;
+ bi_array_ptr capitalRIssuer = NULL;
+ bi_ptr gamma = NULL;
+ bi_ptr capital_gamma = NULL;
+ bi_ptr rho = NULL;
+ bi_ptr r = NULL;
+ bi_ptr rho_double = NULL;
+ bi_t bi_tmp, bi_tmp1, bi_tmp2;
+
+ bi_new(bi_tmp);
+ bi_new(bi_tmp1);
+ bi_new(bi_tmp2);
+ *key_pair_with_proof = NULL;
+
+ // STEP 1
+ LogDebug("Step 1 of 8 - compute modulus n (please wait: long process)\n");
+
+ // FUTURE USAGE if( IS_DEBUG==0)
+ prime_init();
+ p = bi_new_ptr();
+ q = bi_new_ptr();
+ n = bi_new_ptr();
+
+ do {
+ // FUTURE USAGE
+ /* compute_safe_prime( p, length_mod / 2);
+ do {
+ compute_safe_prime( q,
+ length_mod - (length_mod >> 1));
+ } while( bi_cmp( p, q) ==0);
+ } else */
+ {
+ bi_generate_safe_prime(p, length_mod / 2);
+ bi_generate_safe_prime(q, length_mod - (length_mod / 2));
+ LogDebug(".");
+ }
+ // n = p*q
+ bi_mul(n, p, q);
+ } while(bi_length(n) != length_mod);
+
+ pPrime = bi_new_ptr();
+ bi_sub(pPrime, p, bi_1);
+
+ // pPrime = (p - 1) >> 1
+ bi_shift_right(pPrime, pPrime, 1);
+ qPrime = bi_new_ptr();
+ bi_sub(qPrime, q, bi_1);
+
+ // qPrime = (q - 1) >> 1
+ bi_shift_right( qPrime, qPrime, 1);
+ if (bi_is_probable_prime(pPrime) == 0) {
+ LogError("!! pPrime not a prime number: %s", bi_2_hex_char(pPrime));
+ result = TSPERR(TSS_E_INTERNAL_ERROR);
+ goto close;
+ }
+ if (bi_is_probable_prime(qPrime) == 0) {
+ LogError("!! qPrime not a prime number: %s", bi_2_hex_char(qPrime));
+ result = TSPERR(TSS_E_INTERNAL_ERROR);
+ goto close;
+ }
+ LogDebug("p=%s", bi_2_hex_char(p));
+ LogDebug("q=%s", bi_2_hex_char(q));
+ LogDebug("n=%s", bi_2_hex_char(n));
+
+ // STEP 2
+ LogDebug("Step 2 - choose random generator of QR_n");
+ capital_s = bi_new_ptr();
+ compute_generator_quadratic_residue(capital_s, n);
+ LogDebug("capital_s=%s", bi_2_hex_char(capital_s));
+
+ // STEP 3 & 4
+ LogDebug("Step 3 & 4 - compute group elements");
+ product_PQprime = bi_new_ptr();
+ bi_mul( product_PQprime, pPrime, qPrime);
+ pair[ELEMENT] = bi_new_ptr();
+ pair[EXPONENT] = bi_new_ptr();
+
+ LogDebug("product_PQprime=%s [%ld]", bi_2_hex_char(product_PQprime),
+ bi_nbin_size(product_PQprime));
+
+ compute_group_element(pair, capital_s, product_PQprime, n);
+ capital_z = bi_new_ptr();
+ bi_set(capital_z, pair[ELEMENT]);
+ xz = bi_new_ptr();
+ bi_set(xz, pair[EXPONENT]);
+
+ // attributes bases
+ compute_group_element(pair, capital_s, product_PQprime, n);
+ capital_r0 = bi_new_ptr();
+ bi_set(capital_r0, pair[ELEMENT]);
+ x0 = bi_new_ptr();
+ bi_set(x0, pair[EXPONENT]);
+
+ compute_group_element(pair, capital_s, product_PQprime, n);
+ capital_r1 = bi_new_ptr();
+ bi_set(capital_r1, pair[ELEMENT]);
+ x1 = bi_new_ptr();
+ bi_set(x1, pair[EXPONENT]);
+
+ // additional attribute bases
+ length = num_attributes_issuer + num_attributes_receiver;
+ x = ALLOC_BI_ARRAY();
+ bi_new_array(x, length);
+ capital_r = ALLOC_BI_ARRAY();
+ bi_new_array(capital_r, length);
+
+ for (i = 0; i < length; i++) {
+ compute_group_element(pair, capital_s, product_PQprime, n);
+ bi_set(capital_r->array[i], pair[ELEMENT]);
+ bi_set(x->array[i], pair[EXPONENT]);
+ }
+
+ // split capitalR into Receiver and Issuer part
+ capitalRReceiver = ALLOC_BI_ARRAY();
+ bi_new_array2(capitalRReceiver, num_attributes_receiver);
+ for (i = 0; i < num_attributes_receiver; i++)
+ capitalRReceiver->array[i] = capital_r->array[i];
+ capitalRIssuer = ALLOC_BI_ARRAY();
+ bi_new_array2(capitalRIssuer, num_attributes_issuer);
+ for (i = 0; i < num_attributes_issuer; i++)
+ capitalRIssuer->array[i] = capital_r->array[i + num_attributes_receiver];
+
+ // STEP 6a
+ LogDebug("Step 6");
+ gamma = bi_new_ptr();
+ capital_gamma = bi_new_ptr();
+ rho = bi_new_ptr();
+ r = bi_new_ptr();
+ rho_double = bi_new_ptr();
+
+ bi_generate_prime(rho, DAA_PARAM_SIZE_RHO);
+ if (bi_length(rho) != DAA_PARAM_SIZE_RHO) {
+ LogError("rho bit length=%ld", bi_length(rho));
+ result = TSPERR(TSS_E_INTERNAL_ERROR);
+ goto close;
+ }
+
+ do {
+ length = DAA_PARAM_SIZE_MODULUS_GAMMA - DAA_PARAM_SIZE_RHO;
+ do {
+ bi_urandom(r, length);
+ } while(bi_length(r) != length || bi_equals_si(bi_mod(bi_tmp, r, rho), 0));
+
+ // rho is not a dividor of r
+ bi_mul( capital_gamma, rho, r);
+ // capital_gamma ++
+ bi_inc( capital_gamma);
+#ifdef DAA_DEBUG
+ if (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA) {
+ printf("|"); fflush(stdout);
+ } else {
+ printf("."); fflush(stdout);
+ }
+#endif
+ } while (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA ||
+ bi_is_probable_prime(capital_gamma) == 0 );
+
+ // STEP 6b
+ if (bi_equals(bi_sub_si(bi_tmp, capital_gamma, 1),
+ bi_mod(bi_tmp1, bi_mul(bi_tmp2, rho, r), n)) == 0) {
+ LogWarn("capital_gamma-1 != (rho * r) mod n tmp=%s tmp1=%s",
+ bi_2_hex_char(bi_tmp), bi_2_hex_char(bi_tmp1));
+ }
+
+ if (bi_equals(bi_div(bi_tmp, bi_sub_si(bi_tmp1, capital_gamma, 1), rho), r ) == 0) {
+ LogWarn("( capital_gamma - 1)/rho != r");
+ }
+
+ LogDebug("capital_gamma=%s\n", bi_2_hex_char(capital_gamma));
+ do {
+ compute_random_number_star(gamma, capital_gamma);
+ // gamma = (gamma ^ r) mod capital_gamma
+ bi_mod_exp(gamma, gamma, r, capital_gamma);
+ } while (bi_equals(gamma, bi_1));
+ // STEP 7
+ buffer = (BYTE *)malloc(base_nameLength);
+ if (buffer == NULL) {
+ LogError("malloc of %u bytes failed", base_nameLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ memcpy(buffer, base_name, base_nameLength);
+ // all fields are linked to the struct with direct reference
+ public_key = create_DAA_PK(n, capital_s, capital_z, capital_r0, capital_r1, gamma,
+ capital_gamma, rho, capitalRReceiver, capitalRIssuer,
+ base_nameLength, buffer);
+
+ // STEP 8
+ // TODO dynamically load DAAKeyCorrectnessProof
+ LogDebug("Step 8: generate proof (please wait: long process)");
+ TSS_DAA_PK_PROOF_internal *correctness_proof = generate_proof(product_PQprime, public_key,
+ xz, x0, x1, x);
+ if (correctness_proof == NULL) {
+ LogError("creation of correctness_proof failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+
+ *key_pair_with_proof = (KEY_PAIR_WITH_PROOF_internal *)
+ malloc(sizeof(KEY_PAIR_WITH_PROOF_internal));
+ if (*key_pair_with_proof == NULL) {
+ LogError("malloc of %zd bytes failed", sizeof(KEY_PAIR_WITH_PROOF_internal));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+
+ (*key_pair_with_proof)->pk = public_key;
+ (*key_pair_with_proof)->proof = correctness_proof;
+ // all fields are linked to the struct with direct reference
+ (*key_pair_with_proof)->private_key = create_TSS_DAA_PRIVATE_KEY(pPrime, qPrime);
+close:
+ if (result != TSS_SUCCESS) {
+ // remove everything, even numbers that should be stored in a struct
+ FREE_BI(pPrime); // kept if no error
+ FREE_BI(qPrime); // kept if no error
+ FREE_BI(n); // kept if no error
+ // FREE_BI( p);
+ // FREE_BI( q);
+ FREE_BI(capital_s); // kept if no error
+ FREE_BI(capital_z); // kept if no error
+ // FREE_BI(product_PQprime);
+ // FREE_BI(pair[ELEMENT]);
+ // FREE_BI(pair[EXPONENT]);
+ // FREE_BI(xz);
+ FREE_BI(capital_r0); // kept if no error
+ // FREE_BI(x0);
+ FREE_BI(capital_r1); // kept if no error
+ // FREE_BI( x1);
+ // bi_array_ptr x = NULL;
+ // bi_array_ptr capital_r = NULL;
+ // bi_array_ptr capitalRReceiver = NULL;
+ // bi_array_ptr capitalRIssuer = NULL;
+ FREE_BI( gamma); // kept if no error
+ FREE_BI( capital_gamma); // kept if no error
+ FREE_BI( rho); // kept if no error
+ // FREE_BI( r);
+ // FREE_BI( rho_double);
+ if (buffer!=NULL)
+ free(buffer);
+
+ if (public_key != NULL)
+ free(public_key);
+
+ if (*key_pair_with_proof != NULL)
+ free(*key_pair_with_proof);
+ }
+ /*
+ Fields kept by structures
+ TSS_DAA_PK: n
+ capital_s
+ capital_z
+ capital_r0
+ capital_r1
+ gamma
+ capital_gamma
+ rho
+ capitalRReceiver
+ capitalRIssuer
+ base_nameLength
+ buffer
+ TSS_DAA_PRIVATE_KEY:
+ pPrime
+ qPrime
+ */
+ bi_free(bi_tmp);
+ bi_free(bi_tmp1);
+ bi_free(bi_tmp2);
+ FREE_BI(p);
+ FREE_BI(q);
+ FREE_BI(product_PQprime);
+ FREE_BI(pair[ELEMENT]);
+ FREE_BI(pair[EXPONENT]);
+ FREE_BI(xz);
+ FREE_BI(x0);
+ FREE_BI(x0);
+ // bi_array_ptr x = NULL;
+ // bi_array_ptr capital_r = NULL;
+ // bi_array_ptr capitalRReceiver = NULL;
+ // bi_array_ptr capitalRIssuer = NULL;
+ FREE_BI(r);
+ FREE_BI(rho_double);
+
+ return result;
+}
diff --git a/src/tspi/daa/daa_issuer/prime_gen.c b/src/tspi/daa/daa_issuer/prime_gen.c
new file mode 100644
index 0000000..27c4026
--- /dev/null
+++ b/src/tspi/daa/daa_issuer/prime_gen.c
@@ -0,0 +1,327 @@
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004, 2005
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bi.h"
+#include "list.h"
+#include "tsplog.h"
+
+static unsigned long *primes;
+static int primes_length;
+
+/* Generates a random number of bit_length bit length. The first two bits and the last bit of this
+ * number are always set, therefore the number is odd and >= (2^(bit_length-1)+2^(bit_length-2)+1)
+ *
+ * bit_length: The length of the number to be generated, in bits
+ * return: a random number of bitLength bit length with first and last bits set
+ */
+void
+random_odd_bi(bi_ptr bi, int bit_length)
+{
+ if (bit_length > 0) {
+ bi_urandom(bi, bit_length);
+ //bi_generate_prime(bi, bit_length);
+ bi_setbit(bi, 0);
+ bi_setbit(bi, bit_length - 1);
+ bi_setbit(bi, bit_length - 2);
+ }
+}
+
+/* This method generates small prime numbers up to a specified bounds using the Sieve of
+ * Eratosthenes algorithm.
+ *
+ * prime_bound: the upper bound for the primes to be generated
+ * starting_prime: the first prime in the list of primes that is returned
+ * return: list of primes up to the specified bound. Each prime is of type bi_ptr
+ */
+void
+generate_small_primes(int prime_bound, int starting_prime)
+{
+ list_ptr res;
+ int length;
+ int *is_primes;
+ int i;
+ int k;
+ int prime;
+ node_t *current;
+
+ primes_length = 0;
+ res = list_new();
+ if (allocs == NULL) {
+ LogError("malloc of list failed");
+ return;
+ }
+ if ((prime_bound <= 1) || (starting_prime > prime_bound))
+ return;
+
+ if (starting_prime <= 2) {
+ starting_prime = 2;
+ list_add(res, bi_2);
+ }
+ length = (prime_bound - 1) >> 1; // length = (prime_bound -1) / 2;
+ is_primes = (int *)malloc(sizeof(int)*length);
+ if (is_primes == NULL) {
+ LogError("malloc of %zd bytes failed", sizeof(int) * length);
+ return;
+ }
+
+ for (i = 0; i < length; i++)
+ is_primes[i] = 1;
+
+ for (i = 0; i < length; i++) {
+ if (is_primes[i] == 1) {
+ prime = 2 * i + 3;
+ for (k = i + prime; k < length; k+= prime)
+ is_primes[k] = 0;
+
+ if (prime >= starting_prime) {
+ list_add(res, (void *)prime);
+ primes_length++;
+ }
+ }
+ }
+ // converti the list to a table
+ current = res->head; // go to first node
+ primes = (unsigned long *)malloc(sizeof(unsigned long) * primes_length);
+ if (primes == NULL) {
+ LogError("malloc of %d bytes failed",
+ sizeof(unsigned long)*primes_length);
+ return;
+ }
+
+ i = 0;
+ while (current != NULL) {
+ primes[i++] = (unsigned long)current->obj;
+ current = current->next; // traverse through the list
+ }
+
+ free(is_primes);
+ list_freeall(res);
+}
+
+void
+prime_init()
+{
+ generate_small_primes(16384, 3);
+}
+
+/* Test whether the provided pDash or p = 2*pDash + 1 are divisible by any of the small primes
+ * saved in the listOfSmallPrimes. A limit for the largest prime to be tested against can be
+ * specified, but it will be ignored if it exeeds the number of precalculated primes.
+ *
+ * p_dash: the number to be tested (p_dash)
+ * prime_bound: the limit for the small primes to be tested against.
+ */
+static int
+test_small_prime_factors(const bi_ptr p_dash, const unsigned long prime_bound)
+{
+ int sievePassed = 1;
+ unsigned long r;
+ unsigned long small_prime;
+ bi_t temp; bi_new(temp);
+
+ small_prime = 1;
+ int i = 0;
+ while (i < primes_length && small_prime < prime_bound ) {
+ small_prime = primes[i++];
+ // r = p_dash % small_prime
+ bi_mod_si(temp, p_dash, small_prime);
+ r = bi_get_si(temp);
+ // test if pDash = 0 (mod smallPrime)
+ if (r == 0) {
+ sievePassed = 0;
+ break;
+ }
+ // test if p = 0 (mod smallPrime) (or r == smallPrime - r - 1)
+ if (r == (small_prime - r - 1)) {
+ sievePassed = 0;
+ break;
+ }
+ }
+ bi_free(temp);
+
+ return sievePassed;
+}
+
+/* Tests if a is a Miller-Rabin witness for n
+ *
+ * a: number which is supposed to be the witness
+ * n: number to be tested against
+ * return: true if a is Miller-Rabin witness for n, false otherwise
+ */
+int
+is_miller_rabin_witness(const bi_ptr a, const bi_ptr n)
+{
+ bi_t n_1;
+ bi_t temp;
+ bi_t _2_power_t;
+ bi_t u;
+ bi_t x0;
+ bi_t x1;
+ int t = -1;
+ int i;
+
+ bi_new(n_1);
+ bi_new(temp);
+ bi_new(_2_power_t);
+ bi_new(u);
+
+ // n1 = n - 1
+ bi_sub_si(n_1, n, 1);
+
+ // test if n-1 = 2^t*u with t >= 1 && u even
+ do {
+ t++;
+ // _2_power_t = bi_1 << t ( == 2 ^ t)
+ bi_shift_left(_2_power_t, bi_1, t);
+ // u = n_1 / (2 ^ t)
+ bi_div(u, n_1, _2_power_t);
+ } while (bi_equals_si(bi_mod(temp, u, bi_2), 0));
+
+ bi_new(x0);
+ bi_new(x1);
+
+ // x1 = (a ^ u ) % n
+ bi_mod_exp(x1, a, u, n);
+
+ // finished to use u, _2_power_t and temp
+ bi_free(u);
+ bi_free(_2_power_t);
+ bi_free(temp);
+ for (i = 0; i < t; i++) {
+ bi_set(x0, x1);
+
+ // x1 = (x0 ^ 2) % n
+ bi_mod_exp(x1, x0, bi_2, n);
+ if (bi_equals_si(x1, 1) && !bi_equals_si(x0, 1) && !bi_equals(x0, n_1) != 0) {
+ bi_free(x0);
+ bi_free(x1);
+ bi_free(n_1);
+ return 1;
+ }
+ }
+
+ bi_free(x0);
+ bi_free(x1);
+ bi_free(n_1);
+
+ if (!bi_equals(x1, bi_1))
+ return 1;
+
+ return 0;
+}
+
+bi_ptr
+compute_trivial_safe_prime(bi_ptr result, int bit_length)
+{
+ LogDebugFn("Enter");
+ do {
+ bi_generate_prime(result, bit_length-1);
+ bi_shift_left(result, result, 1); // result := result << 1
+ bi_add_si(result, result, 1); // result := result -1
+ if (getenv("TSS_DEBUG_OFF") == NULL) {
+ printf(".");
+ fflush(stdout);
+ }
+ } while (bi_is_probable_prime(result)==0);
+
+ return result;
+}
+
+/* The main method to compute a random safe prime of the specified bit length.
+ * IMPORTANT: The computer prime will have two first bits and the last bit set to 1 !!
+ * i.e. > (2^(bitLength-1)+2^(bitLength-2)+1). This is done to be sure that if two primes of
+ * bitLength n are multiplied, the result will have the bitLenght of 2*n exactly This
+ * implementation uses the algorithm proposed by Ronald Cramer and Victor Shoup in "Signature
+ * Schemes Based on the strong RSA Assumption" May 9, 2000.
+ *
+ * bitLength: the bit length of the safe prime to be computed.
+ * return: a number which is considered to be safe prime
+ */
+bi_ptr
+compute_safe_prime(bi_ptr p, int bit_length)
+{
+ bi_ptr p_dash;
+ bi_ptr temp_p;
+ bi_ptr p_minus_1;
+ int stop;
+ unsigned long prime_bound;
+
+ LogDebug("compute Safe Prime: length: %d bits\n", bit_length);
+
+ p_dash = bi_new_ptr();
+ temp_p = bi_new_ptr();
+ p_minus_1 = bi_new_ptr();
+
+ /* some heuristic checks to limit the number of small primes to check against and the
+ * number of Miller-Rabin primality tests at the end */
+ if (bit_length <= 256) {
+ prime_bound = 768;
+ } else if (bit_length <= 512) {
+ prime_bound = 3072;
+ } else if (bit_length <= 768) {
+ prime_bound = 6144;
+ } else if (bit_length <= 1024) {
+ prime_bound = 1024;
+ } else {
+ prime_bound = 16384;
+ }
+
+ do {
+ stop = 0;
+ /* p_dash = generated random with basic bit settings (odd) */
+ random_odd_bi(p_dash, bit_length - 1);
+
+ if (test_small_prime_factors(p_dash, prime_bound) == 0) {
+ LogDebugFn("1");
+ continue;
+ }
+ /* test if p_dash or p are divisible by some small primes */
+ if (is_miller_rabin_witness(bi_2, p_dash)) {
+ LogDebugFn("2");
+ continue;
+ }
+ /* test if 2^(pDash) = +1/-1 (mod p)
+ * bi can not handle negative operation, we compare to (p-1) instead of -1
+ * calculate p = 2*pDash+1 -> (pDash << 1) + 1
+ */
+ bi_shift_left(p, p_dash, 1);
+ bi_add(p, p, bi_1);
+
+ // p_minus_1:= p - 1
+ bi_sub(p_minus_1, p, bi_1);
+
+ // temp_p := ( 2 ^ p_dash ) mod p
+ bi_mod_exp(temp_p, bi_2, p_dash, p);
+ if (!bi_equals_si(temp_p, 1) && !bi_equals(temp_p, p_minus_1) ) {
+ LogDebugFn("3");
+ continue;
+ }
+
+ // test if pDash or p are divisible by some small primes
+ if (is_miller_rabin_witness(bi_2, p_dash)) {
+ LogDebugFn("4");
+ continue;
+ }
+ // test the library dependent probable_prime
+ if (bi_is_probable_prime(p_dash))
+ stop = 1;
+ } while (stop == 0);
+
+ bi_free(p_minus_1);
+ bi_free(temp_p);
+ bi_free(p_dash);
+
+ LogDebug("found Safe Prime: %s bits", bi_2_hex_char(p));
+
+ return p;
+}
diff --git a/src/tspi/daa/daa_parameter.c b/src/tspi/daa/daa_parameter.c
new file mode 100644
index 0000000..58f240f
--- /dev/null
+++ b/src/tspi/daa/daa_parameter.c
@@ -0,0 +1,184 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include "daa_parameter.h"
+
+setenv("TCSD_FOREGROUND", "1", 1);
+
+static EVP_MD *digest = NULL;
+
+extern EVP_MD *DAA_PARAM_get_message_digest(void) {
+ if( digest == NULL) {
+ OpenSSL_add_all_digests();
+ digest = EVP_get_digestbyname( DAA_PARAM_MESSAGE_DIGEST_ALGORITHM);
+ }
+ return digest;
+}
+
+// from common.c (ltp-tss)
+char *err_string(TSS_RESULT r)
+{
+ /* Check the return code to see if it is common to all layers.
+ * If so, return it.
+ */
+ switch (TSS_ERROR_CODE(r)) {
+ case TSS_SUCCESS: return "TSS_SUCCESS";
+ default:
+ break;
+ }
+
+ /* The return code is either unknown, or specific to a layer */
+ if (TSS_ERROR_LAYER(r) == TSS_LAYER_TPM) {
+ switch (TSS_ERROR_CODE(r)) {
+ case TCPA_E_AUTHFAIL: return "TCPA_E_AUTHFAIL";
+ case TCPA_E_BADINDEX: return "TCPA_E_BADINDEX";
+ case TCPA_E_AUDITFAILURE: return "TCPA_E_AUDITFAILURE";
+ case TCPA_E_CLEAR_DISABLED: return "TCPA_E_CLEAR_DISABLED";
+ case TCPA_E_DEACTIVATED: return "TCPA_E_DEACTIVATED";
+ case TCPA_E_DISABLED: return "TCPA_E_DISABLED";
+ case TCPA_E_DISABLED_CMD: return "TCPA_E_DISABLED_CMD";
+ case TCPA_E_FAIL: return "TCPA_E_FAIL";
+ case TCPA_E_INACTIVE: return "TCPA_E_INACTIVE";
+ case TCPA_E_INSTALL_DISABLED: return "TCPA_E_INSTALL_DISABLED";
+ case TCPA_E_INVALID_KEYHANDLE: return "TCPA_E_INVALID_KEYHANDLE";
+ case TCPA_E_KEYNOTFOUND: return "TCPA_E_KEYNOTFOUND";
+ case TCPA_E_NEED_SELFTEST: return "TCPA_E_NEED_SELFTEST";
+ case TCPA_E_MIGRATEFAIL: return "TCPA_E_MIGRATEFAIL";
+ case TCPA_E_NO_PCR_INFO: return "TCPA_E_NO_PCR_INFO";
+ case TCPA_E_NOSPACE: return "TCPA_E_NOSPACE";
+ case TCPA_E_NOSRK: return "TCPA_E_NOSRK";
+ case TCPA_E_NOTSEALED_BLOB: return "TCPA_E_NOTSEALED_BLOB";
+ case TCPA_E_OWNER_SET: return "TCPA_E_OWNER_SET";
+ case TCPA_E_RESOURCES: return "TCPA_E_RESOURCES";
+ case TCPA_E_SHORTRANDOM: return "TCPA_E_SHORTRANDOM";
+ case TCPA_E_SIZE: return "TCPA_E_SIZE";
+ case TCPA_E_WRONGPCRVAL: return "TCPA_E_WRONGPCRVAL";
+ case TCPA_E_BAD_PARAM_SIZE: return "TCPA_E_BAD_PARAM_SIZE";
+ case TCPA_E_SHA_THREAD: return "TCPA_E_SHA_THREAD";
+ case TCPA_E_SHA_ERROR: return "TCPA_E_SHA_ERROR";
+ case TCPA_E_FAILEDSELFTEST: return "TCPA_E_FAILEDSELFTEST";
+ case TCPA_E_AUTH2FAIL: return "TCPA_E_AUTH2FAIL";
+ case TCPA_E_BADTAG: return "TCPA_E_BADTAG";
+ case TCPA_E_IOERROR: return "TCPA_E_IOERROR";
+ case TCPA_E_ENCRYPT_ERROR: return "TCPA_E_ENCRYPT_ERROR";
+ case TCPA_E_DECRYPT_ERROR: return "TCPA_E_DECRYPT_ERROR";
+ case TCPA_E_INVALID_AUTHHANDLE: return "TCPA_E_INVALID_AUTHHANDLE";
+ case TCPA_E_NO_ENDORSEMENT: return "TCPA_E_NO_ENDORSEMENT";
+ case TCPA_E_INVALID_KEYUSAGE: return "TCPA_E_INVALID_KEYUSAGE";
+ case TCPA_E_WRONG_ENTITYTYPE: return "TCPA_E_WRONG_ENTITYTYPE";
+ case TCPA_E_INVALID_POSTINIT: return "TCPA_E_INVALID_POSTINIT";
+ case TCPA_E_INAPPROPRIATE_SIG: return "TCPA_E_INAPPROPRIATE_SIG";
+ case TCPA_E_BAD_KEY_PROPERTY: return "TCPA_E_BAD_KEY_PROPERTY";
+ case TCPA_E_BAD_MIGRATION: return "TCPA_E_BAD_MIGRATION";
+ case TCPA_E_BAD_SCHEME: return "TCPA_E_BAD_SCHEME";
+ case TCPA_E_BAD_DATASIZE: return "TCPA_E_BAD_DATASIZE";
+ case TCPA_E_BAD_MODE: return "TCPA_E_BAD_MODE";
+ case TCPA_E_BAD_PRESENCE: return "TCPA_E_BAD_PRESENCE";
+ case TCPA_E_BAD_VERSION: return "TCPA_E_BAD_VERSION";
+ case TCPA_E_RETRY: return "TCPA_E_RETRY";
+ default: return "UNKNOWN TPM ERROR";
+ }
+ } else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TDDL) {
+ switch (TSS_ERROR_CODE(r)) {
+ case TSS_E_FAIL: return "TSS_E_FAIL";
+ case TSS_E_BAD_PARAMETER: return "TSS_E_BAD_PARAMETER";
+ case TSS_E_INTERNAL_ERROR: return "TSS_E_INTERNAL_ERROR";
+ case TSS_E_NOTIMPL: return "TSS_E_NOTIMPL";
+ case TSS_E_PS_KEY_NOTFOUND: return "TSS_E_PS_KEY_NOTFOUND";
+ case TSS_E_KEY_ALREADY_REGISTERED: return "TSS_E_KEY_ALREADY_REGISTERED";
+ case TSS_E_CANCELED: return "TSS_E_CANCELED";
+ case TSS_E_TIMEOUT: return "TSS_E_TIMEOUT";
+ case TSS_E_OUTOFMEMORY: return "TSS_E_OUTOFMEMORY";
+ case TSS_E_TPM_UNEXPECTED: return "TSS_E_TPM_UNEXPECTED";
+ case TSS_E_COMM_FAILURE: return "TSS_E_COMM_FAILURE";
+ case TSS_E_TPM_UNSUPPORTED_FEATURE: return "TSS_E_TPM_UNSUPPORTED_FEATURE";
+ case TDDL_E_COMPONENT_NOT_FOUND: return "TDDL_E_COMPONENT_NOT_FOUND";
+ case TDDL_E_ALREADY_OPENED: return "TDDL_E_ALREADY_OPENED";
+ case TDDL_E_BADTAG: return "TDDL_E_BADTAG";
+ case TDDL_E_INSUFFICIENT_BUFFER: return "TDDL_E_INSUFFICIENT_BUFFER";
+ case TDDL_E_COMMAND_COMPLETED: return "TDDL_E_COMMAND_COMPLETED";
+ case TDDL_E_ALREADY_CLOSED: return "TDDL_E_ALREADY_CLOSED";
+ case TDDL_E_IOERROR: return "TDDL_E_IOERROR";
+ default: return "UNKNOWN TDDL ERROR";
+ }
+ } else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TCS) {
+ switch (TSS_ERROR_CODE(r)) {
+ case TSS_E_FAIL: return "TSS_E_FAIL";
+ case TSS_E_BAD_PARAMETER: return "TSS_E_BAD_PARAMETER";
+ case TSS_E_INTERNAL_ERROR: return "TSS_E_INTERNAL_ERROR";
+ case TSS_E_NOTIMPL: return "TSS_E_NOTIMPL";
+ case TSS_E_PS_KEY_NOTFOUND: return "TSS_E_PS_KEY_NOTFOUND";
+ case TSS_E_KEY_ALREADY_REGISTERED: return "TSS_E_KEY_ALREADY_REGISTERED";
+ case TSS_E_CANCELED: return "TSS_E_CANCELED";
+ case TSS_E_TIMEOUT: return "TSS_E_TIMEOUT";
+ case TSS_E_OUTOFMEMORY: return "TSS_E_OUTOFMEMORY";
+ case TSS_E_TPM_UNEXPECTED: return "TSS_E_TPM_UNEXPECTED";
+ case TSS_E_COMM_FAILURE: return "TSS_E_COMM_FAILURE";
+ case TSS_E_TPM_UNSUPPORTED_FEATURE: return "TSS_E_TPM_UNSUPPORTED_FEATURE";
+ case TCS_E_KEY_MISMATCH: return "TCS_E_KEY_MISMATCH";
+ case TCS_E_KM_LOADFAILED: return "TCS_E_KM_LOADFAILED";
+ case TCS_E_KEY_CONTEXT_RELOAD: return "TCS_E_KEY_CONTEXT_RELOAD";
+ case TCS_E_INVALID_CONTEXTHANDLE: return "TCS_E_INVALID_CONTEXTHANDLE";
+ case TCS_E_INVALID_KEYHANDLE: return "TCS_E_INVALID_KEYHANDLE";
+ case TCS_E_INVALID_AUTHHANDLE: return "TCS_E_INVALID_AUTHHANDLE";
+ case TCS_E_INVALID_AUTHSESSION: return "TCS_E_INVALID_AUTHSESSION";
+ case TCS_E_INVALID_KEY: return "TCS_E_INVALID_KEY";
+ default: return "UNKNOWN TCS ERROR";
+ }
+ } else {
+ switch (TSS_ERROR_CODE(r)) {
+ case TSS_E_FAIL: return "TSS_E_FAIL";
+ case TSS_E_BAD_PARAMETER: return "TSS_E_BAD_PARAMETER";
+ case TSS_E_INTERNAL_ERROR: return "TSS_E_INTERNAL_ERROR";
+ case TSS_E_NOTIMPL: return "TSS_E_NOTIMPL";
+ case TSS_E_PS_KEY_NOTFOUND: return "TSS_E_PS_KEY_NOTFOUND";
+ case TSS_E_KEY_ALREADY_REGISTERED: return "TSS_E_KEY_ALREADY_REGISTERED";
+ case TSS_E_CANCELED: return "TSS_E_CANCELED";
+ case TSS_E_TIMEOUT: return "TSS_E_TIMEOUT";
+ case TSS_E_OUTOFMEMORY: return "TSS_E_OUTOFMEMORY";
+ case TSS_E_TPM_UNEXPECTED: return "TSS_E_TPM_UNEXPECTED";
+ case TSS_E_COMM_FAILURE: return "TSS_E_COMM_FAILURE";
+ case TSS_E_TPM_UNSUPPORTED_FEATURE: return "TSS_E_TPM_UNSUPPORTED_FEATURE";
+ case TSS_E_INVALID_OBJECT_TYPE: return "TSS_E_INVALID_OBJECT_TYPE";
+ case TSS_E_INVALID_OBJECT_INITFLAG: return "TSS_E_INVALID_OBJECT_INITFLAG";
+ case TSS_E_INVALID_HANDLE: return "TSS_E_INVALID_HANDLE";
+ case TSS_E_NO_CONNECTION: return "TSS_E_NO_CONNECTION";
+ case TSS_E_CONNECTION_FAILED: return "TSS_E_CONNECTION_FAILED";
+ case TSS_E_CONNECTION_BROKEN: return "TSS_E_CONNECTION_BROKEN";
+ case TSS_E_HASH_INVALID_ALG: return "TSS_E_HASH_INVALID_ALG";
+ case TSS_E_HASH_INVALID_LENGTH: return "TSS_E_HASH_INVALID_LENGTH";
+ case TSS_E_HASH_NO_DATA: return "TSS_E_HASH_NO_DATA";
+ case TSS_E_SILENT_CONTEXT: return "TSS_E_SILENT_CONTEXT";
+ case TSS_E_INVALID_ATTRIB_FLAG: return "TSS_E_INVALID_ATTRIB_FLAG";
+ case TSS_E_INVALID_ATTRIB_SUBFLAG: return "TSS_E_INVALID_ATTRIB_SUBFLAG";
+ case TSS_E_INVALID_ATTRIB_DATA: return "TSS_E_INVALID_ATTRIB_DATA";
+ case TSS_E_NO_PCRS_SET: return "TSS_E_NO_PCRS_SET";
+ case TSS_E_KEY_NOT_LOADED: return "TSS_E_KEY_NOT_LOADED";
+ case TSS_E_KEY_NOT_SET: return "TSS_E_KEY_NOT_SET";
+ case TSS_E_VALIDATION_FAILED: return "TSS_E_VALIDATION_FAILED";
+ case TSS_E_TSP_AUTHREQUIRED: return "TSS_E_TSP_AUTHREQUIRED";
+ case TSS_E_TSP_AUTH2REQUIRED: return "TSS_E_TSP_AUTH2REQUIRED";
+ case TSS_E_TSP_AUTHFAIL: return "TSS_E_TSP_AUTHFAIL";
+ case TSS_E_TSP_AUTH2FAIL: return "TSS_E_TSP_AUTH2FAIL";
+ case TSS_E_KEY_NO_MIGRATION_POLICY: return "TSS_E_KEY_NO_MIGRATION_POLICY";
+ case TSS_E_POLICY_NO_SECRET: return "TSS_E_POLICY_NO_SECRET";
+ case TSS_E_INVALID_OBJ_ACCESS: return "TSS_E_INVALID_OBJ_ACCESS";
+ case TSS_E_INVALID_ENCSCHEME: return "TSS_E_INVALID_ENCSCHEME";
+ case TSS_E_INVALID_SIGSCHEME: return "TSS_E_INVALID_SIGSCHEME";
+ case TSS_E_ENC_INVALID_LENGTH: return "TSS_E_ENC_INVALID_LENGTH";
+ case TSS_E_ENC_NO_DATA: return "TSS_E_ENC_NO_DATA";
+ case TSS_E_ENC_INVALID_TYPE: return "TSS_E_ENC_INVALID_TYPE";
+ case TSS_E_INVALID_KEYUSAGE: return "TSS_E_INVALID_KEYUSAGE";
+ case TSS_E_VERIFICATION_FAILED: return "TSS_E_VERIFICATION_FAILED";
+ case TSS_E_HASH_NO_IDENTIFIER: return "TSS_E_HASH_NO_IDENTIFIER";
+ default: return "UNKNOWN TSS ERROR";
+ }
+ }
+}
diff --git a/src/tspi/daa/daa_platform/platform.c b/src/tspi/daa/daa_platform/platform.c
new file mode 100644
index 0000000..80180ca
--- /dev/null
+++ b/src/tspi/daa/daa_platform/platform.c
@@ -0,0 +1,2644 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// for message digest
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
+
+#include <stdlib.h>
+
+#include "daa_structs.h"
+#include "daa_parameter.h"
+#include "trousers/tss.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include <trousers/trousers.h>
+#include <spi_utils.h>
+#include <obj.h>
+#include "tsplog.h"
+#include "tss/tcs.h"
+#include "platform.h"
+#include "issuer.h"
+#include "verifier.h"
+
+#define EVP_SUCCESS 1
+
+TSS_RESULT
+Tcsip_TPM_DAA_Join(TCS_CONTEXT_HANDLE tcsContext, // in
+ TSS_HDAA hDAA, // in
+ BYTE stage, // in
+ UINT32 inputSize0, // in
+ BYTE* inputData0, // in
+ UINT32 inputSize1, // in
+ BYTE* inputData1, // in
+ TPM_AUTH* ownerAuth, // in/out
+ UINT32* outputSize, // out
+ BYTE** outputData // out
+) {
+ TSS_RESULT result;
+ TSS_HPOLICY hPolicy;
+ TCPA_DIGEST digest;
+ UINT16 offset = 0;
+ BYTE hashblob[10000];
+ TPM_HANDLE hTPM;
+ TPM_HANDLE join_session;
+ // TPM_HANDLE hTPM;
+
+ if( (result = obj_daa_get_handle_tpm( hDAA, &hTPM)) != TSS_SUCCESS)
+ return result;
+ if( (result = obj_daa_get_session_handle( hDAA, &join_session)) != TSS_SUCCESS)
+ return result;
+ LogDebug("Tcsip_TPM_DAA_Join(tcsContext=%x,hDAA=%x,join_session=%x, hTPM=%x stage=%d)",
+ tcsContext,
+ hDAA,
+ join_session,
+ hTPM,
+ stage);
+
+ LogDebug("obj_tpm_get_policy(hTPM=%X)", hTPM);
+ if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS)
+ return result;
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob)");
+ // hash TPM_COMMAND_CODE
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob);
+ LogDebug("Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)");
+ // hash stage
+ Trspi_LoadBlob_BYTE(&offset, stage, hashblob);
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, 0, hashblob)");
+ // hash inputSize0
+ Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob);
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize0:%d", inputSize0);
+ // hash inputData0
+ Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0);
+ // hash inputSize1
+ Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob);
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize1:%d", inputSize1);
+ // hash inputData1
+ Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1);
+ Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
+
+ if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join,
+ hPolicy, &digest,
+ ownerAuth)) != TSS_SUCCESS) return result;
+ LogDebug("secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d", result);
+ LogDebug("TCSP_DAAJoin(%x,%x,stage=%x,%x,%x,%x,%x,%x)\n",
+ tcsContext,
+ hTPM,
+ stage,
+ inputSize0,
+ (int)inputData0,
+ inputSize1,
+ (int)inputData1,
+ (int)&ownerAuth);
+ /* step of the following call:
+ TCSP_DAAJoin tcsd_api/calltcsapi.c (define in spi_utils.h)
+ TCSP_DAAJoin_TP tcsd_api/tcstp.c (define in trctp.h)
+ */
+ result = TCSP_DaaJoin( tcsContext,
+ join_session,
+ stage,
+ inputSize0, inputData0,
+ inputSize1, inputData1,
+ ownerAuth,
+ outputSize, outputData);
+ if( result != TSS_SUCCESS) return result;
+
+ offset = 0;
+ Trspi_LoadBlob_UINT32(&offset, result, hashblob);
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob);
+ Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob);
+ Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData);
+ LogDebug("TCSP_DAAJoin stage=%d outputSize=%d outputData=%x RESULT=%d",
+ (int)stage, (int)*outputSize, (int)outputData, (int)result);
+ Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
+ if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, ownerAuth))) {
+ LogError("obj_policy_validate_auth=%d", result);
+ }
+ return result;
+}
+
+TSS_RESULT Tcsip_TPM_DAA_Sign( TCS_CONTEXT_HANDLE hContext, // in
+ TPM_HANDLE handle, // in
+ BYTE stage, // in
+ UINT32 inputSize0, // in
+ BYTE* inputData0, // in
+ UINT32 inputSize1, // in
+ BYTE* inputData1, // in
+ TPM_AUTH* ownerAuth, // in, out
+ UINT32* outputSize, // out
+ BYTE** outputData // out
+) {
+ TSS_RESULT result;
+ TSS_HPOLICY hPolicy;
+ TCPA_DIGEST digest;
+ UINT16 offset = 0;
+ BYTE hashblob[1000];
+ TPM_HANDLE hTPM;
+ TPM_HANDLE session_handle;
+ TSS_HDAA hDAA = (TSS_HDAA)handle;
+ // TPM_HANDLE hTPM;
+
+ if( (result = obj_daa_get_handle_tpm( hDAA, &hTPM)) != TSS_SUCCESS)
+ return result;
+ if( (result = obj_daa_get_session_handle( hDAA, &session_handle)) != TSS_SUCCESS)
+ return result;
+ LogDebug("Tcsip_TPM_DAA_Sign(tcsContext=%x,hDAA=%x,sign_session=%x, hTPM=%x stage=%d)",
+ hContext,
+ hDAA,
+ session_handle,
+ hTPM,
+ stage);
+
+ LogDebug("obj_tpm_get_policy(hTPM=%X)", hTPM);
+ if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS)
+ return result;
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob)");
+ // hash TPM_COMMAND_CODE
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob);
+ LogDebug("Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)");
+ // hash stage
+ Trspi_LoadBlob_BYTE(&offset, stage, hashblob);
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, 0, hashblob)");
+ // hash inputSize0
+ Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob);
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize0:%d", inputSize0);
+ // hash inputData0
+ Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0);
+ // hash inputSize1
+ Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob);
+ LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize1:%d", inputSize1);
+ // hash inputData1
+ Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1);
+ Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
+
+ if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join,
+ hPolicy, &digest,
+ ownerAuth)) != TSS_SUCCESS) return result;
+ LogDebug("secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d", result);
+ LogDebug("TCSP_DAASign(%x,%x,stage=%x,%x,%x,%x,%x,%x)",
+ hContext,
+ hTPM,
+ stage,
+ inputSize0,(int)inputData0,
+ inputSize1,(int)inputData1,
+ (int)&ownerAuth);
+ /* step of the following call:
+ TCSP_DAASign tcsd_api/calltcsapi.c (define in spi_utils.h)
+ TCSP_DAASign_TP tcsd_api/tcstp.c (define in trctp.h)
+ */
+ result = TCSP_DaaSign( hContext,
+ session_handle,
+ stage,
+ inputSize0, inputData0,
+ inputSize1, inputData1,
+ ownerAuth,
+ outputSize, outputData);
+ if( result != TSS_SUCCESS) return result;
+
+ offset = 0;
+ Trspi_LoadBlob_UINT32(&offset, result, hashblob);
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob);
+ Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob);
+ Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData);
+ LogDebug("TCSP_DAASign stage=%d outputSize=%d outputData=%x RESULT=%d",
+ (int)stage, (int)*outputSize, (int)outputData, (int)result);
+ Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
+ if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, ownerAuth)))
+ {
+ LogError("obj_policy_validate_auth=%d", result);
+ }
+ return result;
+}
+
+/**
+ Only used for the logging
+*/
+static TSS_RESULT
+Tcsip_TPM_DAA_Join_encapsulate(TCS_CONTEXT_HANDLE tcsContext, // in
+ TSS_HDAA hDAA, // in
+ BYTE stage, // in
+ UINT32 inputSize0, // in
+ BYTE* inputData0, // in
+ UINT32 inputSize1, // in
+ BYTE* inputData1, // in
+ TPM_AUTH* ownerAuth, // in/out
+ UINT32* outputSize, // out
+ BYTE** outputData // out
+) {
+ TSS_RESULT result;
+
+ LogDebug("Tcsip_DAA_Join(TCS_CONTEXT=%X,TSS_HDAA=%X,stage=%d,\
+ inputSize0=%u,inputData0=%s\ninputSize1=%u,inputData1=%s,ownerAuth=%X)",
+ tcsContext, hDAA, stage,
+ inputSize0, dump_byte_array(inputSize0, inputData0),
+ inputSize1,dump_byte_array(inputSize1, inputData1),
+ (int)ownerAuth);
+ result = Tcsip_TPM_DAA_Join(
+ tcsContext, // in
+ hDAA, // in
+ stage, // in
+ inputSize0, // in
+ inputData0, // in
+ inputSize1, // in
+ inputData1, // in
+ ownerAuth, // in/out
+ outputSize, // out
+ outputData // out
+ );
+ LogDebug("Tcsip_DAA_Join(stage=%d,outputSize=%u outputData=%s ownerAuth=%X) result=%d",
+ (int)stage, *outputSize, dump_byte_array( *outputSize, *outputData), (int)ownerAuth, result);
+ return result;
+}
+
+#if 0
+/* from TSS.java */
+/* openssl RSA (struct rsa_st) could manage RSA Key */
+TSS_RESULT
+Tspi_TPM_DAA_JoinInit_internal( TSS_HDAA hDAA,
+ TSS_HTPM hTPM,
+ int daa_counter,
+ TSS_DAA_PK *issuer_pk,
+ int issuer_authentication_PKLengh,
+ RSA **issuer_authentication_PK,
+ int issuer_authentication_PK_signaturesLength,
+ BYTE **issuer_authentication_PK_signatures,
+ int *capital_UprimeLength,
+ BYTE **capital_Uprime,
+ TSS_DAA_IDENTITY_PROOF *identity_proof,
+ TSS_DAA_JOIN_SESSION *join_session)
+{
+ // Optional: verification of the PKDAA and issuer settings (authen. by the RSA Public Key chain)
+ TSS_RESULT result;
+ TCS_CONTEXT_HANDLE tcsContext;
+ TPM_AUTH ownerAuth;
+ int i, modulus_length, outputSize, length, length1;
+ UINT32 return_join_session;
+ BYTE *outputData, *issuer_settings_bytes;
+ BYTE *buffer_modulus;
+ TPM_DAA_ISSUER *issuer_settings;
+ char buffer[1000], buffer1[1000];
+ TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK( issuer_pk);
+ bi_ptr issuer_authentication_PK_i = NULL;
+
+ if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS)
+ return result;
+ obj_daa_set_handle_tpm( hDAA, hTPM);
+
+ // stages 0-2 explained in the diagram "Keys of DAA Issuer"
+ // issuer_authentication_PKLengh should be converted to Network Based integer
+ i = htonl(issuer_authentication_PKLengh);
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 0,
+ sizeof(int), (BYTE *)(&i),
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) { goto close;}
+ // set the sessionHandle to the returned value
+ return_join_session = ntohl( *((UINT32 *)outputData));
+ free( outputData);
+ obj_daa_set_session_handle( hDAA, return_join_session);
+
+ LogDebug("done join 0 settings join_session:%x\n", return_join_session);
+ modulus_length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
+ buffer_modulus = malloc(modulus_length);
+ if (buffer_modulus == NULL) {
+ LogError("malloc of %d bytes failed", modulus_length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ issuer_authentication_PK_i = bi_new_ptr();
+ for(i =0; i< issuer_authentication_PKLengh; i++) {
+ bi_set_as_BIGNUM( issuer_authentication_PK_i, issuer_authentication_PK[i]->n);
+ bi_2_byte_array( buffer_modulus,
+ modulus_length,
+ issuer_authentication_PK_i);
+ if ( i==0) {
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 1,
+ modulus_length, buffer_modulus,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) {
+ free( buffer_modulus);
+ goto close;
+ }
+ } else {
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 1,
+ modulus_length, buffer_modulus,
+ DAA_PARAM_KEY_SIZE / 8, issuer_authentication_PK_signatures[i -1],
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) {
+ free( buffer_modulus);
+ goto close;
+ }
+ }
+ }
+ free( buffer_modulus);
+ LogDebug("done join 1-%d\n", issuer_authentication_PKLengh);
+ // define issuer_settings
+ issuer_settings = convert2issuer_settings( pk_internal);
+ issuer_settings_bytes = issuer_2_byte_array( issuer_settings, &length);
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 2,
+ length, issuer_settings_bytes,
+ modulus_length,
+ issuer_authentication_PK_signatures[issuer_authentication_PKLengh-1],
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) { goto close;}
+ LogDebug("done join 2\n");
+ i = htonl( daa_counter);
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 3,
+ sizeof(UINT32), (BYTE *)(&i),
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) { goto close;}
+ LogDebug("done join 3\n");
+ // reserved another buffer for storing Big Integer
+ bi_2_nbin1( &length, buffer, pk_internal->capitalR0);
+ bi_2_nbin1( &length1, buffer1, pk_internal->modulus);
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 4,
+ length, buffer,
+ length1, buffer1,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) { goto close;}
+ LogDebug("done join 4\n");
+ bi_2_nbin1( &length, buffer, pk_internal->capitalR1);
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 5,
+ length, buffer,
+ length1, buffer1,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) { goto close;}
+ LogDebug("done join 5\n");
+ bi_2_nbin1( &length, buffer, pk_internal->capitalS);
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 6,
+ length, buffer,
+ length1, buffer1,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) { goto close;}
+ LogDebug("done join 6\n");
+ bi_2_nbin1( &length, buffer, pk_internal->capitalSprime);
+ // define Uprime
+ result = Tcsip_TPM_DAA_Join_encapsulate(
+ tcsContext, hDAA,
+ 7,
+ length, buffer,
+ length1, buffer1,
+ &ownerAuth, &outputSize, &outputData);
+ // 5 : save PKDAA, U, daaCount and sessionHandle in joinSession
+ join_session->issuerPk = (TSS_HKEY)issuer_pk;
+ if( result == TSS_SUCCESS) {
+ *capital_UprimeLength = outputSize;
+ *capital_Uprime = convert_alloc( tcsContext, outputSize, outputData);
+ if (*capital_Uprime == NULL) {
+ LogError("malloc of %d bytes failed", outputSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ join_session->capitalUPrime = copy_alloc( tcsContext,
+ *capital_UprimeLength,
+ *capital_Uprime);
+ if (join_session->capitalUPrime == NULL) {
+ LogError("malloc of %d bytes failed", *capital_UprimeLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ join_session->capitalUPrimeLength = *capital_UprimeLength;
+ }
+ join_session->sessionHandle = return_join_session;
+ // get the endorsement Key (public part)
+ result = get_public_EK(
+ hTPM, // in
+ &( identity_proof->endorsementLength),
+ &( identity_proof->endorsementCredential)
+ );
+
+close:
+ FREE_BI( issuer_authentication_PK_i);
+ LogDebug("result = %d", result);
+ LogDebug("outputSize=%d", outputSize);
+ LogDebug("outputData=%s", dump_byte_array( outputSize, outputData));
+ return result;
+}
+#else
+TSS_RESULT
+Tspi_TPM_DAA_JoinInit_internal(TSS_HTPM hTPM,
+ TSS_HDAA_ISSUER_KEY hIssuerKey
+ UINT32 daa_counter,
+ UINT32 issuerAuthPKsLength,
+ TSS_HKEY* issuerAuthPKs,
+ UINT32 issuerAuthPKSignaturesLength,
+ UINT32 issuerAuthPKSignaturesLength2,
+ BYTE** issuerAuthPKSignatures,
+ UINT32* capitalUprimeLength,
+ BYTE** capitalUprime,
+ TSS_DAA_IDENTITY_PROOF** identity_proof,
+ UINT32* joinSessionLength,
+ BYTE** joinSession)
+{
+ // Optional: verification of the PKDAA and issuer settings (authen. by the RSA Public Key chain)
+ TSS_RESULT result;
+ TSS_HCONTEXT tspContext;
+ TPM_AUTH ownerAuth;
+ int length, length1;
+ UINT32 i, modulus_length, outputSize, buf_len;
+ BYTE *outputData, *issuer_settings_bytes;
+ BYTE *modulus, stage, *buf;
+ //TPM_DAA_ISSUER *issuer_settings;
+ //char buffer[1000], buffer1[1000];
+ //TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK(issuer_pk);
+ bi_ptr issuerAuthPK = NULL;
+ TPM_HANDLE daaHandle;
+ Trspi_HashCtx hashCtx;
+ TPM_DIGEST digest;
+ TSS_DAA_IDENTITY_PROOF daaIdentityProof;
+
+ if ((result = obj_tpm_is_connected(hTPM, &tspContext)))
+ return result;
+
+ if ((result = obj_daaissuerkey_get_daa_handle(hIssuerKey, &daaHandle)))
+ return result;
+
+ stage = 0;
+ inputSize0 = (UINT32)sizeof(UINT32);
+ inputData0 = issuerAuthPKsLength;
+ inputSize1 = 0;
+ inputData1 = NULL;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DAA_Join);
+ result |= Trspi_Hash_BYTE(&hashCtx, stage);
+ result |= Trspi_Hash_UINT32(&hashCtx, inputSize0);
+ result |= Trspi_HashUpdate(&hashCtx, inputSize0, inputData0);
+ result |= Trspi_Hash_UINT32(&hashCtx, inputSize1);
+ result |= Trspi_HashUpdate(&hashCtx, inputSize1, inputData1);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ return result;
+
+ // stages 0-2 explained in the diagram "Keys of DAA Issuer"
+ if ((result = TCS_API(tspContext)->DaaJoin(tspContext, daaHandle, stage, inputSize1,
+ inputData0, inputSize1, inputData1, &ownerAuth,
+ &outputSize, &outputData)))
+ goto close;
+
+ if (outputSize != sizeof(UINT32)) {
+ result = TSPERR(TSS_E_INTERNAL_ERROR);
+ goto close;
+ }
+
+ // set the sessionHandle to the returned value
+ Trspi_UnloadBlob_UINT32(&offset, &daaHandle, outputData);
+ free(outputData);
+ if ((result = obj_daaissuerkey_set_daa_handle(hIssuerKey, daaHandle)))
+ goto close;
+
+ LogDebug("done join 0 settings join_session:%x", daaHandle);
+
+ modulus_length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
+ if ((buffer_modulus = malloc(modulus_length)) == NULL) {
+ LogError("malloc of %d bytes failed", modulus_length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+
+ stage = 1;
+ for (i = 0; i < issuerAuthPKsLength; i++) {
+ if ((result = obj_rsakey_get_modulus(issuerAuthPKs[i], &modulus_length, &modulus)))
+ goto close;
+
+ outputData = NULL;
+ if (i==0) {
+ result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage,
+ modulus_length, modulus, 0, NULL,
+ &ownerAuth, &outputSize,
+ &outputData);
+ } else {
+ result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage,
+ modulus_length, modulus,
+ issuerAuthPKSignaturesLength2,
+ issuerAuthPKSignatures[i - 1],
+ &ownerAuth, &outputSize,
+ &outputData);
+ }
+
+ free(outputData);
+ free_tspi(tspContext, modulus);
+ if (result != TSS_SUCCESS) {
+ LogDebugFn("Stage 1 iteration %u failed", i);
+ goto close;
+ }
+ }
+
+ LogDebug("done join 1-%d\n", issuer_authentication_PKLengh);
+
+ stage = 2;
+ // define issuer_settings
+#if 0
+ issuer_settings = convert2issuer_settings(pk_internal);
+ issuer_settings_bytes = issuer_2_byte_array(issuer_settings, &length);
+#else
+ if ((result = obj_daaissuerkey_get_daa_issuer(hIssuerKey, &issuer_length, &issuer)))
+ goto close;
+
+ if ((result = obj_daaissuerkey_get_modulus(hIssuerKey, &modulus_length, &modulus))) {
+ free_tspi(tspContext, issuer);
+ goto close;
+ }
+#endif
+ if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, issuer_length,
+ issuer, issuerAuthPKSignaturesLength2,
+ issuerAuthPKSignatures[i - 1], &ownerAuth,
+ &outputSize, &outputData))) {
+ free_tspi(tspContext, issuer);
+ free_tspi(tspContext, modulus);
+ goto close;
+ }
+ free_tspi(tspContext, issuer);
+
+ LogDebug("done join 2\n");
+
+ stage = 3;
+ if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, sizeof(UINT32),
+ (BYTE *)(&daa_counter), 0, NULL, &ownerAuth,
+ &outputSize, &outputData)))
+ goto close;
+
+ LogDebug("done join 3\n");
+
+ stage = 4;
+#if 0
+ // reserved another buffer for storing Big Integer
+ bi_2_nbin1( &length, buffer, pk_internal->capitalR0);
+ bi_2_nbin1( &length1, buffer1, pk_internal->modulus);
+#else
+ if ((result = obj_daaissuerkey_get_capitalR0(hIssuerKey, &buf_len, &buf)))
+ return result;
+#endif
+ if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf,
+ modulus_length, modulus, &ownerAuth,
+ &outputSize, &outputData))) {
+ free_tspi(tspContext, buf);
+ free_tspi(tspContext, modulus);
+ goto close;
+ }
+ free_tspi(tspContext, buf);
+
+ LogDebug("done join 4\n");
+
+ stage = 5;
+#if 0
+ bi_2_nbin1( &length, buffer, pk_internal->capitalR1);
+#else
+ if ((result = obj_daaissuerkey_get_capitalR1(hIssuerKey, &buf_len, &buf)))
+ return result;
+#endif
+ if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len,
+ buf, modulus_length, modulus, &ownerAuth,
+ &outputSize, &outputData))) {
+ free_tspi(tspContext, buf);
+ free_tspi(tspContext, modulus);
+ goto close;
+ }
+ free_tspi(tspContext, buf);
+
+ LogDebug("done join 5\n");
+
+ stage = 6;
+#if 0
+ bi_2_nbin1( &length, buffer, pk_internal->capitalS);
+#else
+ if ((result = obj_daaissuerkey_get_capitalS(hIssuerKey, &buf_len, &buf)))
+ return result;
+#endif
+ if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf,
+ modulus_length, modulus, &ownerAuth,
+ &outputSize, &outputData))) {
+ free_tspi(tspContext, buf);
+ free_tspi(tspContext, modulus);
+ goto close;
+ }
+ free_tspi(tspContext, buf);
+
+ LogDebug("done join 6\n");
+
+ stage = 7;
+#if 0
+ bi_2_nbin1( &length, buffer, pk_internal->capitalSprime);
+#else
+ if ((result = obj_daaissuerkey_get_capitalSprime(hIssuerKey, &buf_len, &buf)))
+ return result;
+#endif
+ // define Uprime
+ if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf,
+ modulus_length, modulus, &ownerAuth,
+ &outputSize, &outputData))) {
+ free_tspi(tspContext, buf);
+ free_tspi(tspContext, modulus);
+ goto close;
+ }
+ free_tspi(tspContext, buf);
+
+#if 0
+ // 5 : save PKDAA, U, daaCount and sessionHandle in joinSession
+ join_session->issuerPk = (TSS_HKEY)issuer_pk;
+ if( result == TSS_SUCCESS) {
+ *capital_UprimeLength = outputSize;
+ *capital_Uprime = convert_alloc( tspContext, outputSize, outputData);
+ if (*capital_Uprime == NULL) {
+ LogError("malloc of %d bytes failed", outputSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ join_session->capitalUPrime = copy_alloc( tspContext,
+ *capital_UprimeLength,
+ *capital_Uprime);
+ if (join_session->capitalUPrime == NULL) {
+ LogError("malloc of %d bytes failed", *capital_UprimeLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ join_session->capitalUPrimeLength = *capital_UprimeLength;
+ }
+ join_session->sessionHandle = return_join_session;
+ // get the endorsement Key (public part)
+ result = get_public_EK(
+ hTPM, // in
+ &( identity_proof->endorsementLength),
+ &( identity_proof->endorsementCredential)
+ );
+#else
+ /* fill out the identity proof struct */
+ if ((result = TCS_API(obj->tspContext)->GetTPMCapability(obj->tspContext, TPM_CAP_VERSION,
+ 0, NULL, &buf_len, &buf)))
+ goto close;
+
+ offset = 0;
+ Trspi_UnloadBlob_VERSION(&offset, buf, &daaIdentityProof.versionInfo);
+ free_tspi(tspContext, buf);
+
+#error set all 3 credentials in the daaIdentityProof struct here
+
+ /* set the U data */
+ if ((result = __tspi_add_mem_entry(tspContext, outputData)))
+ goto close;
+ *capitalUPrime = outputData;
+ *capitalUPrimeLength = outputSize;
+
+ /* return the TSS specific stuff */
+#endif
+
+close:
+ FREE_BI( issuer_authentication_PK_i);
+ LogDebug("result = %d", result);
+ LogDebug("outputSize=%d", outputSize);
+ LogDebug("outputData=%s", dump_byte_array( outputSize, outputData));
+ return result;
+}
+#endif
+
+
+/* allocation:
+ endorsementKey as BYTE *
+*/
+TSS_RESULT
+get_public_EK(TSS_HTPM hTPM,
+ UINT32 *endorsementKeyLength,
+ BYTE **endorsementKey
+
+) {
+ TSS_RESULT result;
+ TSS_HKEY hEk;
+ TSS_HPOLICY hTpmPolicy;
+ UINT32 uiAttrSize;
+ BYTE *pAttr;
+
+ if( (result = obj_tpm_get_policy( hTPM, &hTpmPolicy)) != TSS_SUCCESS) {
+ LogError("can not retrieve policy from the TPM handler");
+ goto out_close;
+ }
+
+ if( (result = Tspi_TPM_GetPubEndorsementKey(hTPM, TRUE, NULL, &hEk)) != TSS_SUCCESS) {
+ LogError("can not retrieve the Public endorsed Key");
+ goto out_close;
+ }
+
+ result = Tspi_GetAttribData(
+ hEk,
+ TSS_TSPATTRIB_KEY_INFO,
+ TSS_TSPATTRIB_KEYINFO_VERSION,
+ &uiAttrSize,
+ &pAttr);
+
+ if (result != TSS_SUCCESS) goto out_close;
+ LogDebug("keyinfo:%s", dump_byte_array( uiAttrSize, pAttr));
+
+ result = Tspi_GetAttribData(
+ hEk,
+ TSS_TSPATTRIB_KEY_BLOB,
+ TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY,
+ endorsementKeyLength,
+ endorsementKey);
+
+ LogDebug("Public Endorsement Key:%s",
+ dump_byte_array( *endorsementKeyLength, *endorsementKey));
+out_close:
+ return result;
+}
+
+// from TSS.java (479)
+TSS_RESULT
+compute_join_challenge_host(TSS_HDAA hDAA,
+ TSS_DAA_PK_internal *pk_internal,
+ bi_ptr capitalU,
+ bi_ptr capital_Uprime,
+ bi_ptr capital_utilde,
+ bi_ptr capital_utilde_prime,
+ bi_ptr capital_ni,
+ bi_ptr capital_ni_tilde,
+ UINT32 commitments_proofLength,
+ TSS_DAA_ATTRIB_COMMIT_internal *
+ commitments_proof,
+ UINT32 nonceIssuerLength,
+ BYTE* nonceIssuer,
+ UINT32 *resultLength,
+ BYTE **result) {
+ EVP_MD_CTX mdctx;
+ BYTE *encoded_pk = NULL, *buffer;
+ UINT32 encoded_pkLength;
+ int rv, length;
+
+ buffer = (BYTE *)malloc( 10000); // to be sure, and it will be free quickly
+ if (buffer == NULL) {
+ LogError("malloc of %d bytes failed", 10000);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ // EVP_MD_CTX_init(&mdctx);
+ rv = EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ if (rv != EVP_SUCCESS) goto err;
+ // allocation
+ encoded_pk = encoded_DAA_PK_internal( &encoded_pkLength, pk_internal);
+ LogDebug("encoded issuerPk[%d]: %s",
+ encoded_pkLength,
+ dump_byte_array( encoded_pkLength, encoded_pk));
+ rv = EVP_DigestUpdate(&mdctx, encoded_pk, encoded_pkLength);
+ if (rv != EVP_SUCCESS) goto err;
+ // capitalU
+ length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
+ bi_2_byte_array( buffer, length, capitalU);
+ LogDebug("capitalU[%ld]: %s",
+ bi_nbin_size(capitalU) ,
+ dump_byte_array( length, buffer));
+ rv = EVP_DigestUpdate(&mdctx, buffer, length);
+ if (rv != EVP_SUCCESS) goto err;
+ // capital UPrime
+ bi_2_byte_array( buffer, length, capital_Uprime);
+ LogDebug("capitalUPrime[%d]: %s",
+ length,
+ dump_byte_array( length, buffer));
+ rv = EVP_DigestUpdate(&mdctx, buffer, length);
+ if (rv != EVP_SUCCESS) goto err;
+ // capital Utilde
+ bi_2_byte_array( buffer, length, capital_utilde);
+ LogDebug("capitalUTilde[%d]: %s",
+ length,
+ dump_byte_array( length, buffer));
+ rv = EVP_DigestUpdate(&mdctx, buffer, length);
+ if (rv != EVP_SUCCESS) goto err;
+ // capital UtildePrime
+ bi_2_byte_array( buffer, length, capital_utilde_prime);
+ LogDebug("capital_utilde_prime[%d]: %s",
+ length,
+ dump_byte_array( length, buffer));
+ rv = EVP_DigestUpdate(&mdctx, buffer, length);
+ if (rv != EVP_SUCCESS) goto err;
+ //capital_ni
+ length = DAA_PARAM_SIZE_MODULUS_GAMMA / 8;
+ bi_2_byte_array( buffer, length, capital_ni);
+ LogDebug("capital_ni[%d]: %s",
+ length,
+ dump_byte_array( length, buffer));
+ rv = EVP_DigestUpdate(&mdctx, buffer, length);
+ if (rv != EVP_SUCCESS) goto err;
+ //capital_ni_tilde
+ bi_2_byte_array( buffer, length, capital_ni_tilde);
+ LogDebug("capital_ni_tilde[%d]: %s",
+ length,
+ dump_byte_array( length, buffer));
+ rv = EVP_DigestUpdate(&mdctx, buffer, length);
+ if (rv != EVP_SUCCESS) goto err;
+ // TODO: commitments
+ LogDebug("nonceIssuer[%d]: %s",
+ nonceIssuerLength,
+ dump_byte_array( nonceIssuerLength, nonceIssuer));
+ rv = EVP_DigestUpdate(&mdctx, nonceIssuer, nonceIssuerLength);
+ if (rv != EVP_SUCCESS) goto err;
+ *resultLength = EVP_MD_CTX_size(&mdctx);
+ *result = (BYTE *)malloc( *resultLength);
+ if (*result == NULL) {
+ LogError("malloc of %d bytes failed", *resultLength);
+ free( buffer);
+ free( encoded_pk);
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+ rv = EVP_DigestFinal(&mdctx, *result, NULL);
+ if (rv != EVP_SUCCESS) goto err;
+ free( buffer);
+ free( encoded_pk);
+ return TSS_SUCCESS;
+err:
+ free( buffer);
+ free( encoded_pk);
+ DEBUG_print_openssl_errors();
+ return TSPERR(TSS_E_INTERNAL_ERROR);
+}
+
+/*
+This is the second out of 3 functions to execute in order to receive a DAA Credential. It
+computes the credential request for the DAA Issuer, which also includes the Platforms & DAA
+public key and the attributes that were chosen by the Platform, and which are not visible to \
+the DAA Issuer. The Platform can commit to the attribute values it has chosen.
+Code influenced by TSS.java (TssDaaCredentialRequest)
+*/
+TSPICALL
+Tspi_TPM_DAA_JoinCreateDaaPubKey_internal(
+ TSS_HDAA hDAA, // in
+ TSS_HTPM hTPM, // in
+ UINT32 authenticationChallengeLength, // in
+ BYTE* authenticationChallenge, // in
+ UINT32 nonceIssuerLength, // in
+ BYTE* nonceIssuer, // in
+ UINT32 attributesPlatformLength, // in
+ BYTE** attributesPlatform, // in
+ TSS_DAA_JOIN_SESSION* joinSession, // in, out
+ TSS_DAA_CREDENTIAL_REQUEST* credentialRequest // out
+) {
+ TSS_RESULT result;
+ TCS_CONTEXT_HANDLE tcsContext;
+ TPM_AUTH ownerAuth;
+ bi_ptr tmp1 = bi_new_ptr();
+ bi_ptr tmp2 = bi_new_ptr();
+ bi_ptr capital_utilde = bi_new_ptr();
+ bi_ptr v_tilde_prime = bi_new_ptr();
+ bi_ptr rv_tilde_prime = bi_new_ptr();
+ bi_ptr capitalU = bi_new_ptr();
+ bi_ptr product_attributes = bi_new_ptr();
+ bi_ptr capital_ni = NULL;
+ bi_ptr capital_utilde_prime = NULL;
+ bi_ptr capital_ni_tilde = NULL;
+ bi_ptr n = NULL;
+ bi_ptr attributePlatform = NULL;
+ bi_ptr c = NULL;
+ bi_ptr zeta = NULL;
+ bi_ptr capital_Uprime = NULL;
+ bi_ptr sv_tilde_prime = NULL;
+ bi_ptr s_f0 = NULL;
+ bi_ptr s_f1 = NULL;
+ bi_ptr sv_prime = NULL;
+ bi_ptr sv_prime1 = NULL;
+ bi_ptr sv_prime2 = NULL;
+ bi_array_ptr ra = NULL;
+ bi_array_ptr sa = NULL;
+ TSS_DAA_PK* pk_extern = (TSS_DAA_PK *)joinSession->issuerPk;
+ TSS_DAA_PK_internal* pk_internal = e_2_i_TSS_DAA_PK( pk_extern);
+ UINT32 i, outputSize, authentication_proofLength, nonce_tpmLength;
+ UINT32 capitalSprime_byte_arrayLength, size_bits, length, chLength, c_byteLength;
+ UINT32 internal_cbyteLength, noncePlatformLength;
+ BYTE *outputData, *authentication_proof, *capitalSprime_byte_array = NULL, *buffer;
+ BYTE *ch = NULL;
+ BYTE *c_byte, *noncePlatform, *nonce_tpm;
+ BYTE *internal_cbyte = NULL;
+ EVP_MD_CTX mdctx;
+
+ if( tmp1 == NULL || tmp2 == NULL || capital_utilde == NULL ||
+ v_tilde_prime == NULL || rv_tilde_prime == NULL ||
+ capitalU == NULL || product_attributes == NULL) {
+ LogError("malloc of bi(s) failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ if( pk_internal == NULL) {
+ LogError("malloc of pk_internal failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) {
+ goto close;
+ }
+ obj_daa_set_handle_tpm( hDAA, hTPM);
+ // allocation
+ n = bi_set_as_nbin( pk_extern->modulusLength, pk_extern->modulus);
+ if( n == NULL) {
+ LogError("malloc of %d bytes failed", pk_extern->modulusLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // allocation
+ capitalSprime_byte_array = bi_2_nbin( &capitalSprime_byte_arrayLength,
+ pk_internal->capitalSprime);
+ if( capitalSprime_byte_array == NULL) {
+ LogError("malloc of %d bytes failed", capitalSprime_byte_arrayLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // compute second part of the credential request
+ // encode plateform attributes (the one visible only by the receiver)
+ bi_set( product_attributes, bi_1);
+ for( i=0; i<attributesPlatformLength; i++) {
+ attributePlatform = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
+ attributesPlatform[i]); // allocation
+ if( attributePlatform == NULL) {
+ LogError("malloc of bi <%s> failed", "attributePlatform");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // bi_tmp1 = ( capitalRReceiver[i] ^ attributesPlatform ) % n
+ bi_mod_exp( tmp1, pk_internal->capitalRReceiver->array[i], attributePlatform, n);
+ // bi_tmp1 = bi_tmp1 * product_attributes
+ bi_mul( tmp1, tmp1, product_attributes);
+ // product_attributes = bi_tmp1 % n
+ bi_mod( product_attributes, tmp1, n);
+ bi_free_ptr( attributePlatform);
+ }
+ bi_urandom( v_tilde_prime, DAA_PARAM_SIZE_RSA_MODULUS +
+ DAA_PARAM_SAFETY_MARGIN);
+ // tmp1 = capitalUPrime * capitalS
+ bi_free_ptr( tmp1);
+ tmp1 = bi_set_as_nbin( joinSession->capitalUPrimeLength,
+ joinSession->capitalUPrime); // allocation
+ if( tmp1 == NULL) {
+ LogError("malloc of %d bytes failed", joinSession->capitalUPrimeLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // U = ( U' * ( ( pk->S ^ v~' ) % n) ) % n
+ // tmp2 = ( pk->S ^ v~') % n
+ bi_mod_exp( tmp2, pk_internal->capitalS, v_tilde_prime, n);
+ // U = tmp1( U') * tmp2
+ bi_mul( capitalU, tmp1, tmp2);
+ bi_mod( capitalU, capitalU, n);
+ // U = ( U * product_attributes ) % n
+ bi_mul( capitalU, capitalU, product_attributes);
+ bi_mod( capitalU, capitalU, n);
+ // 2 : call the TPM to compute authentication proof with U'
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 8,
+ authenticationChallengeLength, authenticationChallenge,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 8");
+ authentication_proof = calloc_tspi( tcsContext, outputSize);
+ if( authentication_proof == NULL) {
+ LogError("malloc of %d bytes failed", outputSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ memcpy( authentication_proof, outputData, outputSize);
+ free( outputData);
+ authentication_proofLength = outputSize;
+
+ // 3 : call the TPM to compute U' (first part of correctness proof of the credential
+ // request
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 9,
+ pk_extern->capitalR0Length, pk_extern->capitalR0,
+ pk_extern->modulusLength, pk_extern->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 9: capitalR0");
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 10,
+ pk_extern->capitalR1Length, pk_extern->capitalR1,
+ pk_extern->modulusLength, pk_extern->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 10: capitalR1");
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 11,
+ pk_extern->capitalSLength, pk_extern->capitalS,
+ pk_extern->modulusLength, pk_extern->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 11: capitalS");
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 12,
+ capitalSprime_byte_arrayLength, capitalSprime_byte_array,
+ pk_extern->modulusLength, pk_extern->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 12: capitalUTildePrime");
+ capital_utilde_prime = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( capital_utilde_prime == NULL) {
+ LogError("malloc of %d bytes failed", outputSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ // 4 compute pseudonym with respect to the DAA Issuer
+ // allocation
+ zeta = compute_zeta( pk_internal->issuerBaseNameLength,
+ pk_internal->issuerBaseName,
+ pk_internal);
+ if( zeta == NULL) {
+ LogError("malloc of bi <%s> failed", "zeta");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ buffer = (BYTE *)malloc( TPM_DAA_SIZE_w);
+ if( buffer == NULL) {
+ LogError("malloc of %d bytes failed", TPM_DAA_SIZE_w);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug("zeta[%ld] = %s", bi_nbin_size( zeta), bi_2_hex_char( zeta));
+ bi_2_byte_array( buffer, TPM_DAA_SIZE_w, zeta);
+ LogDebug("zeta[%d] = %s", TPM_DAA_SIZE_w, dump_byte_array( TPM_DAA_SIZE_w, buffer));
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 13,
+ pk_extern->capitalGammaLength, pk_extern->capitalGamma,
+ TPM_DAA_SIZE_w, buffer, // zeta
+ &ownerAuth, &outputSize, &outputData);
+ free( buffer);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 13: capitalGamma / zeta");
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 14,
+ pk_extern->capitalGammaLength, pk_extern->capitalGamma,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 14: capitalGamma");
+ capital_ni = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( capital_ni == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_ni");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 15,
+ pk_extern->capitalGammaLength, pk_extern->capitalGamma,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 15: capitalGamma");
+ capital_ni_tilde = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( capital_ni_tilde == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_ni_tilde");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+
+ // 5 : compute the second part of the correctness proof of the credential request
+ // (with attributes not visible to issuer)
+ // randomize/blind attributesReceiver
+ size_bits = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES;
+ bi_set( product_attributes, bi_1);
+ ra = (bi_array_ptr)malloc( sizeof( struct _bi_array));
+ if( ra == NULL) {
+ LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_new_array( ra, attributesPlatformLength);
+ if( ra->array == NULL) {
+ LogError("malloc of bi_array <%s> failed", "ra");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( i=0; i < attributesPlatformLength; i++) {
+ bi_urandom( ra->array[i], size_bits);
+ LogDebug("ra[i]=%s size=%d", bi_2_hex_char( ra->array[i]), size_bits);
+ // product_attributes=(((capitalYplatform ^ ra[i]) % n)*<product_attributes-1>)%n
+ bi_mod_exp( tmp1, pk_internal->capitalRReceiver->array[i], ra->array[i], n);
+ bi_mul( tmp1, tmp1, product_attributes);
+ bi_mod( product_attributes, tmp1, n);
+ }
+ size_bits = DAA_PARAM_SIZE_F_I+2*DAA_PARAM_SAFETY_MARGIN+DAA_PARAM_SIZE_MESSAGE_DIGEST;
+ bi_urandom( rv_tilde_prime, size_bits);
+ // capital_utilde = ( capitalS ^ rv_tilde_prime) % n
+ bi_mod_exp( capital_utilde, pk_internal->capitalS, rv_tilde_prime, n);
+ // capital_utilde = capital_utilde * product_attributes
+ bi_mul( capital_utilde, capital_utilde, product_attributes);
+ // capital_utilde = capital_utilde % n
+ bi_mod( capital_utilde, capital_utilde, n);
+ // 5e
+ capital_Uprime = bi_set_as_nbin( joinSession->capitalUPrimeLength,
+ joinSession->capitalUPrime); // allocation
+ if( capital_Uprime == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_Uprime");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug("calculation UTilde: capitalS:%s\n", bi_2_hex_char( pk_internal->capitalS));
+ LogDebug("calculation UTilde: rv_tilde_prime:%s\n", bi_2_hex_char( rv_tilde_prime));
+ LogDebug("calculation UTilde: n:%s\n", bi_2_hex_char( n));
+ LogDebug("calculation UTilde: product_attributes:%s\n", bi_2_hex_char( product_attributes));
+ LogDebug("calculation NItilde: ntilde:%s\n", bi_2_hex_char( capital_ni_tilde));
+
+ result = compute_join_challenge_host(
+ hDAA,
+ pk_internal,
+ capitalU,
+ capital_Uprime,
+ capital_utilde,
+ capital_utilde_prime,
+ capital_ni,
+ capital_ni_tilde,
+ 0, // TODO commitmentProofLength
+ NULL, // TODO commitment
+ nonceIssuerLength,
+ nonceIssuer,
+ &chLength, // out
+ &ch // out allocation
+ );
+ if( result != TSS_SUCCESS) goto close;
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 16,
+ chLength, ch,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ nonce_tpm = outputData;
+ nonce_tpmLength = outputSize;
+ LogDebug("Done Join 16: compute_join_challenge_host return nonce_tpm:%s",
+ dump_byte_array(nonce_tpmLength, nonce_tpm));
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 17,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ s_f0 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( s_f0 == NULL) {
+ LogError("malloc of <bi> %s failed", "s_f0");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug("Done Join 17: return sF0:%s", dump_byte_array(outputSize, outputData) );
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 18,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ s_f1 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( s_f1 == NULL) {
+ LogError("malloc of <bi> %s failed", "s_f1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug("Done Join 18: return sF1:%s", dump_byte_array(outputSize, outputData) );
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 19,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 19: return sv_prime1");
+ sv_prime1 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( sv_prime1 == NULL) {
+ LogError("malloc of <bi> %s failed", "sv_prime1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 20,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 20: return cByte");
+ c_byte = (BYTE *)calloc_tspi( tcsContext, outputSize);
+ if( c_byte == NULL) {
+ LogError("malloc of %d bytes failed", outputSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ memcpy( c_byte, outputData, outputSize);
+ free( outputData);
+ c_byteLength = outputSize;
+ c = bi_set_as_nbin( c_byteLength, c_byte); // allocation
+ if( c == NULL) {
+ LogError("malloc of <bi> %s failed", "c");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+
+ // verify computation of c by TPM
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ EVP_DigestUpdate(&mdctx, ch, chLength);
+ EVP_DigestUpdate(&mdctx, nonce_tpm, nonce_tpmLength);
+ nonce_tpm = convert_alloc( tcsContext, nonce_tpmLength, nonce_tpm); // allocation
+ if( nonce_tpm == NULL) {
+ LogError("malloc of %d bytes failed", nonce_tpmLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ internal_cbyteLength = EVP_MD_CTX_size(&mdctx);
+ internal_cbyte = (BYTE *)malloc( internal_cbyteLength);
+ if( internal_cbyte == NULL) {
+ LogError("malloc of %d bytes failed", internal_cbyteLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ EVP_DigestFinal(&mdctx, internal_cbyte, NULL);
+ if( c_byteLength != internal_cbyteLength ||
+ memcmp( c_byte, internal_cbyte, c_byteLength) != 0) {
+ LogError( "Computation of c in TPM DAA Join command is incorrect. Affected stages: 16,20\n");
+ LogError( "\t c_byte[%d] %s",
+ c_byteLength,
+ dump_byte_array( c_byteLength, c_byte));
+ LogError( "\tc_internal_byte[%d] %s",
+ internal_cbyteLength,
+ dump_byte_array( internal_cbyteLength, internal_cbyte));
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+
+ // 5m) blind attributesReceiver
+ sa = (bi_array_ptr)malloc( sizeof( struct _bi_array));
+ if( sa == NULL) {
+ LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_new_array( sa, attributesPlatformLength);
+ for( i=0; i < attributesPlatformLength; i++) {
+ attributePlatform = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
+ attributesPlatform[i]); // allocation
+ if( attributePlatform == NULL) {
+ LogError("malloc of <bi> %s failed", "attributePlatform");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug("calculating sa[%d]: raLength=%ld cLength=%ld attributesPlatformLength=%ld\n",
+ i, bi_nbin_size( ra->array[i]), bi_nbin_size( c), bi_nbin_size( attributePlatform));
+ bi_add( sa->array[i], ra->array[i], bi_mul( tmp1, c, attributePlatform));
+ bi_free_ptr( attributePlatform);
+ }
+ attributePlatform = NULL;
+ // 5o) Commitments
+ // TODO
+
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 21,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 21: return sv_prime2");
+ sv_prime2 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( sv_prime2 == NULL) {
+ LogError("malloc of <bi> %s failed", "sv_prime2");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ sv_prime = bi_new_ptr();
+ if( sv_prime == NULL) {
+ LogError("malloc of <bi> %s failed", "sv_prime");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // sv_prime = sv_prime2 << DAA_PARAM_SIZE_SPLIT_EXPONENT
+ bi_shift_left( sv_prime, sv_prime2, DAA_PARAM_SIZE_SPLIT_EXPONENT);
+ // sv_prime = sv_prime + sv_prime1
+ bi_add( sv_prime, sv_prime, sv_prime1);
+
+ sv_tilde_prime = bi_new_ptr();
+ // tmp1 = c * v_tilde_prime
+ bi_mul( tmp1, c, v_tilde_prime);
+ // sv_tilde_prime = rv_tilde_prime + tmp1
+ bi_add( sv_tilde_prime, rv_tilde_prime, tmp1);
+
+ // step 6) - choose nonce
+ bi_urandom( tmp1, DAA_PARAM_SAFETY_MARGIN * 8);
+ noncePlatform = (BYTE *)calloc_tspi( tcsContext, DAA_PARAM_SAFETY_MARGIN);
+ if( noncePlatform == NULL) {
+ LogError("malloc of <bi> %s failed", "noncePlatform");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &noncePlatformLength, noncePlatform, tmp1);
+
+ LogDebug("challenge:%s", dump_byte_array( c_byteLength, c_byte));
+ LogDebug("sF0 [%ld]:%s", bi_length( s_f0), bi_2_hex_char( s_f0));
+ LogDebug("sF1 [%ld]:%s", bi_length( s_f1), bi_2_hex_char( s_f1));
+ LogDebug("sv_prime [%ld]:%s", bi_length( sv_prime), bi_2_hex_char( sv_prime));
+ LogDebug("sv_tilde_prime [%ld]:%s", bi_length( sv_tilde_prime), bi_2_hex_char( sv_tilde_prime));
+ // update joinSession
+ joinSession->capitalU = calloc_tspi( tcsContext, bi_nbin_size( capitalU));
+ if( joinSession->capitalU == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( capitalU));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(joinSession->capitalULength),
+ joinSession->capitalU,
+ capitalU);
+ joinSession->attributesPlatformLength = attributesPlatformLength;
+ joinSession->attributesPlatform = calloc_tspi( tcsContext, sizeof(BYTE *));
+ for( i=0; i<joinSession->attributesPlatformLength; i++) {
+ joinSession->attributesPlatform[i] =
+ calloc_tspi( tcsContext,DAA_PARAM_SIZE_F_I / 8);
+ memcpy( joinSession->attributesPlatform[i],
+ attributesPlatform[i],
+ DAA_PARAM_SIZE_F_I / 8);
+ }
+ joinSession->noncePlatform = noncePlatform;
+ joinSession->noncePlatformLength = noncePlatformLength;
+ joinSession->vTildePrime = calloc_tspi( tcsContext, bi_nbin_size( v_tilde_prime));
+ if( joinSession->vTildePrime == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( v_tilde_prime));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(joinSession->vTildePrimeLength),
+ joinSession->vTildePrime,
+ v_tilde_prime);
+ // update credentialRequest
+ credentialRequest->capitalU = calloc_tspi( tcsContext, bi_nbin_size( capitalU));
+ if( credentialRequest->capitalU == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( capitalU));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credentialRequest->capitalULength),
+ credentialRequest->capitalU,
+ capitalU);
+ credentialRequest->capitalNi = calloc_tspi( tcsContext, bi_nbin_size( capital_ni));
+ if( credentialRequest->capitalNi == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( capital_ni));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credentialRequest->capitalNiLength),
+ credentialRequest->capitalNi,
+ capital_ni);
+ credentialRequest->authenticationProofLength = authentication_proofLength;
+ credentialRequest->authenticationProof = authentication_proof;
+ credentialRequest->challenge = c_byte;
+ credentialRequest->challengeLength = c_byteLength;
+ credentialRequest->nonceTpm = nonce_tpm;
+ credentialRequest->nonceTpmLength = nonce_tpmLength;
+ credentialRequest->noncePlatform = noncePlatform;
+ credentialRequest->noncePlatformLength = DAA_PARAM_SAFETY_MARGIN;
+ credentialRequest->sF0 = calloc_tspi( tcsContext, bi_nbin_size( s_f0));
+ if( credentialRequest->sF0 == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( s_f0));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credentialRequest->sF0Length), credentialRequest->sF0, s_f0);
+ credentialRequest->sF1 = calloc_tspi( tcsContext, bi_nbin_size( s_f1));
+ if( credentialRequest->sF1 == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( s_f1));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credentialRequest->sF1Length), credentialRequest->sF1, s_f1);
+ credentialRequest->sVprime = calloc_tspi( tcsContext, bi_nbin_size( sv_prime));
+ if( credentialRequest->sVprime == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( sv_prime));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credentialRequest->sVprimeLength),
+ credentialRequest->sVprime,
+ sv_prime);
+ credentialRequest->sVtildePrime = calloc_tspi( tcsContext, bi_nbin_size( sv_tilde_prime));
+ if( credentialRequest->sVtildePrime == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( sv_tilde_prime));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(credentialRequest->sVtildePrimeLength),
+ credentialRequest->sVtildePrime,
+ sv_tilde_prime);
+ length = (DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8;
+ LogDebug("SA length=%d", sa->length);
+ credentialRequest->sA = calloc_tspi( tcsContext, sizeof( BYTE *) * sa->length);
+ if( credentialRequest->sA == NULL) {
+ LogError("malloc of %d bytes failed", sizeof( BYTE *) * sa->length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+
+ for( i=0; i<(UINT32)sa->length; i++) {
+ LogDebug("sa[%d].size=%d", i, (int)bi_nbin_size( sa->array[i]));
+ credentialRequest->sA[i] = calloc_tspi( tcsContext, length);
+ if( credentialRequest->sA[i] == NULL) {
+ LogError("malloc of %d bytes failed", length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // size used only as repository
+ bi_2_byte_array( credentialRequest->sA[i], length, sa->array[i]);
+ }
+ credentialRequest->sALength = sa->length;
+close:
+ if( capitalSprime_byte_array!=NULL) free( capitalSprime_byte_array);
+ if( ch!=NULL) free( ch);
+ if( internal_cbyte != NULL) free( internal_cbyte);
+ bi_free_ptr( rv_tilde_prime);
+ bi_free_ptr( v_tilde_prime);
+ bi_free_ptr( capital_utilde);
+ bi_free_ptr( tmp1);
+ bi_free_ptr( tmp2);
+ bi_free_ptr( capitalU);
+ if( ra != NULL) {
+ bi_free_array( ra);
+ free( ra);
+ }
+ if( sa != NULL) {
+ bi_free_array( sa);
+ free( sa);
+ }
+ FREE_BI( capital_ni);
+ FREE_BI( capital_utilde_prime);
+ FREE_BI( capital_ni_tilde);
+ FREE_BI( n);
+ FREE_BI( attributePlatform);
+ FREE_BI( c);
+ FREE_BI( zeta);
+ FREE_BI( capital_Uprime);
+ FREE_BI( sv_tilde_prime);
+ FREE_BI( s_f0);
+ FREE_BI( s_f1);
+ FREE_BI( sv_prime);
+ FREE_BI( sv_prime1);
+ FREE_BI( sv_prime2);
+ FREE_BI( product_attributes);
+ free_TSS_DAA_PK_internal( pk_internal);
+ return result;
+}
+
+/*
+Code influenced by TSS.java (joinStoreCredential)
+*/
+TSPICALL Tspi_TPM_DAA_JoinStoreCredential_internal
+(
+ TSS_HDAA hDAA, // in
+ TSS_HTPM hTPM, // in
+ TSS_DAA_CRED_ISSUER credIssuer, // in
+ TSS_DAA_JOIN_SESSION joinSession, // in
+ TSS_HKEY* hDaaCredential // out
+) {
+ TCS_CONTEXT_HANDLE tcsContext;
+ TPM_AUTH ownerAuth;
+ bi_ptr tmp1 = bi_new_ptr();
+ bi_ptr tmp2 = bi_new_ptr();
+ bi_ptr n = NULL;
+ bi_ptr e = NULL;
+ bi_ptr fraction_A = NULL;
+ bi_ptr v_prime_prime = NULL;
+ bi_ptr capital_U = NULL;
+ bi_ptr product_attributes = NULL;
+ bi_ptr capital_Atilde = NULL;
+ bi_ptr s_e = NULL;
+ bi_ptr c_prime = NULL;
+ bi_ptr capital_A = NULL;
+ bi_ptr product = NULL;
+ bi_ptr v_tilde_prime = NULL;
+ bi_ptr v_prime_prime0 = NULL;
+ bi_ptr v_prime_prime1 = NULL;
+ TSS_DAA_PK *daa_pk_extern;
+ TSS_DAA_PK_internal *pk_intern = NULL;
+ TSS_DAA_CREDENTIAL *daaCredential;
+ bi_array_ptr attributes_issuer;
+ TSS_RESULT result = TSS_SUCCESS;
+ UINT32 i;
+ UINT32 c_byteLength, v0Length, v1Length, tpm_specificLength;
+ BYTE *c_byte = NULL;
+ BYTE *v0 = NULL;
+ BYTE *v1 = NULL;
+ BYTE *tpm_specific = NULL;
+
+ if( tmp1 == NULL || tmp2 == NULL) {
+ LogError("malloc of bi(s) failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) return result;
+ obj_daa_set_handle_tpm( hDAA, hTPM);
+
+ LogDebug("Converting issuer public");
+ daa_pk_extern = (TSS_DAA_PK *)joinSession.issuerPk;
+ pk_intern = e_2_i_TSS_DAA_PK( daa_pk_extern);
+ if( pk_intern == NULL) {
+ LogError("malloc of pk_intern failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ n = bi_new_ptr();
+ if( n == NULL) {
+ LogError("malloc of bi <%s> failed", "n");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( n, pk_intern->modulus);
+ attributes_issuer = (bi_array_ptr)malloc( sizeof( struct _bi_array));
+ if( attributes_issuer == NULL) {
+ LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_new_array( attributes_issuer, credIssuer.attributesIssuerLength);
+ if( attributes_issuer->array == NULL) {
+ LogError("malloc of bi_array <%s> failed", "attributes_issuer->array");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( i=0; i < credIssuer.attributesIssuerLength; i++) {
+ // allocation
+ attributes_issuer->array[i] = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
+ credIssuer.attributesIssuer[i]);
+ if( attributes_issuer->array[i] == NULL) {
+ LogError("malloc of bi <attributes_issuer->array[%d]> failed", i);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ }
+ LogDebug("verify credential of issuer ( part 1)");
+ e = bi_set_as_nbin( credIssuer.eLength, credIssuer.e); // allocation
+ if( e == NULL) {
+ LogError("malloc of bi <%s> failed", "e");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( tmp1, bi_0);
+ bi_setbit( tmp1, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1);
+ bi_set( tmp2, bi_0);
+ bi_setbit( tmp1, DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE - 1);
+ bi_add( tmp1, tmp1, tmp2);
+ if( bi_is_probable_prime( e) == 0 ||
+ bi_length(e) < DAA_PARAM_SIZE_EXPONENT_CERTIFICATE ||
+ bi_cmp( e, tmp1) > 0) {
+ LogError("Verification e failed - Step 1.a");
+ LogError("\tPrime(e):%d", bi_is_probable_prime( e));
+ LogError("\tbit_length(e):%ld", bi_length(e));
+ LogError("\te > (2^(l_e) + 2^(l_prime_e)):%d", bi_cmp( e, tmp1));
+ result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR;
+ goto close;
+ }
+ LogDebug("verify credential of issuer (part 2) with proof");
+ fraction_A = bi_new_ptr();
+ if( fraction_A == NULL) {
+ LogError("malloc of bi <%s> failed", "fraction_A");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ v_prime_prime = bi_set_as_nbin( credIssuer.vPrimePrimeLength,
+ credIssuer.vPrimePrime); // allocation
+ if( v_prime_prime == NULL) {
+ LogError("malloc of bi <%s> failed", "v_prime_prime");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capital_U = bi_set_as_nbin( joinSession.capitalULength,
+ joinSession.capitalU); // allocation
+ if( capital_U == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_U");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( fraction_A, pk_intern->capitalS, v_prime_prime, n);
+ bi_mul( fraction_A, fraction_A, capital_U);
+ bi_mod( fraction_A, fraction_A, n);
+ LogDebug("encode attributes");
+ product_attributes = bi_new_ptr();
+ bi_set( product_attributes, bi_1);
+ for( i=0; i<(UINT32)attributes_issuer->length; i++) {
+ bi_mod_exp( tmp1, pk_intern->capitalRIssuer->array[i],
+ attributes_issuer->array[i], n);
+ bi_mul( product_attributes, tmp1, product_attributes);
+ bi_mod( product_attributes, product_attributes, n);
+ }
+ bi_mul( fraction_A, fraction_A, product_attributes);
+ bi_mod( fraction_A, fraction_A, n);
+ capital_Atilde = bi_new_ptr();
+ if( capital_Atilde == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_Atilde");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_invert_mod( capital_Atilde, fraction_A, n);
+ bi_mul( capital_Atilde, capital_Atilde, pk_intern->capitalZ);
+ bi_mod( capital_Atilde, capital_Atilde, n);
+ s_e = bi_set_as_nbin( credIssuer.sELength, credIssuer.sE); // allocation
+ if( s_e == NULL) {
+ LogError("malloc of bi <%s> failed", "s_e");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( capital_Atilde, capital_Atilde, s_e, n);
+ c_prime = bi_set_as_nbin( credIssuer.cPrimeLength, credIssuer.cPrime); // allocation
+ if( c_prime == NULL) {
+ LogError("malloc of bi <%s> failed", "c_prime");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capital_A = bi_set_as_nbin( credIssuer.capitalALength, credIssuer.capitalA); // allocation
+ if( capital_A == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_A");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( tmp1, capital_A, c_prime, n);
+ bi_mul( capital_Atilde, capital_Atilde, tmp1);
+ bi_mod( capital_Atilde, capital_Atilde, n);
+
+ result = compute_join_challenge_issuer( pk_intern,
+ v_prime_prime,
+ capital_A,
+ capital_Atilde,
+ joinSession.noncePlatformLength,
+ joinSession.noncePlatform,
+ &c_byteLength,
+ &c_byte); // out allocation
+ if( result != TSS_SUCCESS) goto close;
+ if( credIssuer.cPrimeLength != c_byteLength ||
+ memcmp( credIssuer.cPrime, c_byte, c_byteLength)!=0) {
+ LogError("Verification of c failed - Step 1.c.i");
+ LogError("credentialRequest.cPrime[%d]=%s",
+ credIssuer.cPrimeLength,
+ dump_byte_array( credIssuer.cPrimeLength, credIssuer.cPrime) );
+ LogError("challenge[%d]=%s",
+ c_byteLength,
+ dump_byte_array( c_byteLength, c_byte) );
+ result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR;
+ goto close;
+ }
+ product = bi_new_ptr();
+ if( product == NULL) {
+ LogError("malloc of bi <%s> failed", "product");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( product, capital_A, e, n);
+ bi_mul( product, product, fraction_A);
+ bi_mod( product, product, n);
+ if( bi_equals( pk_intern->capitalZ, product) == 0) {
+ LogError("Verification of A failed - Step 1.c.ii");
+ LogError("\tcapitalZ=%s", bi_2_hex_char( pk_intern->capitalZ));
+ LogError("\tproduct=%s", bi_2_hex_char( product));
+ result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR;
+ goto close;
+ }
+ v_tilde_prime = bi_set_as_nbin( joinSession.vTildePrimeLength,
+ joinSession.vTildePrime); // allocation
+ bi_add( v_prime_prime, v_prime_prime, v_tilde_prime);
+ bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT);
+ v_prime_prime0 = bi_new_ptr();
+ if( v_prime_prime0 == NULL) {
+ LogError("malloc of bi <%s> failed", "v_prime_prime0");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod( v_prime_prime0, v_prime_prime, tmp1);
+ v_prime_prime1 = bi_new_ptr();
+ if( v_prime_prime1 == NULL) {
+ LogError("malloc of bi <%s> failed", "v_prime_prime1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_shift_right( v_prime_prime1, v_prime_prime, DAA_PARAM_SIZE_SPLIT_EXPONENT);
+ free( c_byte);
+ c_byte = (BYTE *)malloc( TPM_DAA_SIZE_v0);
+ if( c_byte == NULL) {
+ LogError("malloc of %d bytes failed", TPM_DAA_SIZE_v0);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_byte_array( c_byte, TPM_DAA_SIZE_v0, v_prime_prime0);
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 22,
+ TPM_DAA_SIZE_v0, c_byte,
+ 0, NULL,
+ &ownerAuth, &v0Length, &v0);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 22: return v0");
+ free( c_byte);
+ c_byte = (BYTE *)malloc( TPM_DAA_SIZE_v1);
+ if( c_byte == NULL) {
+ LogError("malloc of %d bytes failed", TPM_DAA_SIZE_v1);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_byte_array( c_byte, TPM_DAA_SIZE_v1, v_prime_prime1);
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 23,
+ TPM_DAA_SIZE_v1, c_byte,
+ 0, NULL,
+ &ownerAuth, &v1Length, &v1);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug("Done Join 23: return v1");
+ result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
+ 24,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &tpm_specificLength, &tpm_specific);
+ if( result != TSS_SUCCESS) goto close;
+
+ daaCredential = (TSS_DAA_CREDENTIAL *)hDaaCredential;
+ daaCredential->capitalA = calloc_tspi( tcsContext, bi_nbin_size( capital_A));
+ if( daaCredential->capitalA == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( capital_A));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaCredential->capitalALength), daaCredential->capitalA, capital_A);
+ daaCredential->exponent = calloc_tspi( tcsContext, bi_nbin_size( e));
+ if( daaCredential->exponent == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( e));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaCredential->exponentLength), daaCredential->exponent, e);
+ daaCredential->vBar0 = calloc_tspi( tcsContext, v0Length);
+ if( daaCredential->vBar0 == NULL) {
+ LogError("malloc of %d bytes failed", v0Length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ daaCredential->vBar0Length = v0Length;
+ memcpy( daaCredential->vBar0, v0, v0Length);
+ LogDebug("vBar0[%d]=%s",
+ daaCredential->vBar0Length,
+ dump_byte_array( daaCredential->vBar0Length, daaCredential->vBar0));
+ daaCredential->vBar1 = calloc_tspi( tcsContext, v1Length);
+ if( daaCredential->vBar1 == NULL) {
+ LogError("malloc of %d bytes failed", v1Length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ daaCredential->vBar1Length = v1Length;
+ memcpy( daaCredential->vBar1, v1, v1Length);
+ LogDebug("vBar1[%d]=%s",
+ daaCredential->vBar1Length,
+ dump_byte_array( daaCredential->vBar1Length, daaCredential->vBar1));
+ //TODO remove
+ LogDebug("[BUSS] joinSession.attributesPlatformLength=%d",
+ joinSession.attributesPlatformLength);
+ LogDebug("[BUSS] credIssuer.attributesIssuerLength=%d",
+ credIssuer.attributesIssuerLength);
+ daaCredential->attributesLength = joinSession.attributesPlatformLength +
+ credIssuer.attributesIssuerLength;
+ daaCredential->attributes = (BYTE **)calloc_tspi( tcsContext,
+ sizeof(BYTE *) * daaCredential->attributesLength);
+ if( daaCredential->attributes == NULL) {
+ LogError("malloc of %d bytes failed",
+ sizeof(BYTE *) * daaCredential->attributesLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( i=0; i < joinSession.attributesPlatformLength; i++) {
+ daaCredential->attributes[i] = calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8);
+ if( daaCredential->attributes[i] == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug("allocation attributes[%d]=%lx", i, (long)daaCredential->attributes[i]);
+ memcpy( daaCredential->attributes[i],
+ joinSession.attributesPlatform[i],
+ DAA_PARAM_SIZE_F_I / 8);
+ }
+ for( i=0; i < credIssuer.attributesIssuerLength; i++) {
+ daaCredential->attributes[i+joinSession.attributesPlatformLength] =
+ calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8);
+ if( daaCredential->attributes[i+joinSession.attributesPlatformLength] == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ memcpy( daaCredential->attributes[i+joinSession.attributesPlatformLength],
+ credIssuer.attributesIssuer[i], DAA_PARAM_SIZE_F_I / 8);
+ }
+ memcpy( &(daaCredential->issuerPK), daa_pk_extern, sizeof( TSS_DAA_PK));
+ daaCredential->tpmSpecificEnc = calloc_tspi( tcsContext, tpm_specificLength);
+ if( daaCredential->tpmSpecificEnc == NULL) {
+ LogError("malloc of %d bytes failed", tpm_specificLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ daaCredential->tpmSpecificEncLength = tpm_specificLength;
+ memcpy( daaCredential->tpmSpecificEnc, tpm_specific, tpm_specificLength);
+ // TODO store in TSS this TSS_DAA_CREDENTIAL_REQUEST
+ *hDaaCredential = (TSS_HKEY)daaCredential;
+close:
+ if( v0 != NULL) free( v0);
+ if( v1 != NULL) free( v1);
+ if( tpm_specific != NULL) free( tpm_specific);
+ if( c_byte != NULL) free( c_byte);
+ bi_free_ptr( tmp2);
+ bi_free_ptr( tmp1);
+ if( attributes_issuer != NULL) {
+ bi_free_array( attributes_issuer);
+ free( attributes_issuer);
+ }
+ FREE_BI( v_prime_prime1);
+ FREE_BI( v_prime_prime0);
+ FREE_BI( v_tilde_prime);
+ FREE_BI( product);
+ FREE_BI( capital_A);
+ FREE_BI( c_prime);
+ FREE_BI( s_e);
+ FREE_BI( capital_Atilde);
+ FREE_BI( product_attributes);
+ FREE_BI( capital_U);
+ FREE_BI( v_prime_prime);
+ FREE_BI( fraction_A);
+ FREE_BI( e);
+ FREE_BI( n);
+ if( pk_intern!=NULL) free_TSS_DAA_PK_internal( pk_intern);
+ return result;
+}
+
+static void add_splitet( bi_ptr result, bi_ptr a, bi_ptr b) {
+ bi_shift_left( result, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT);
+ bi_mul( result, result, b);
+ bi_add( result, result, a);
+}
+
+/* code influenced by TSS.java (signStep) */
+TSS_RESULT Tspi_TPM_DAA_Sign_internal
+(
+ TSS_HDAA hDAA, // in
+ TSS_HTPM hTPM, // in
+ TSS_HKEY hDaaCredential, // in
+ TSS_DAA_SELECTED_ATTRIB revealAttributes, // in
+ UINT32 verifierBaseNameLength, // in
+ BYTE* verifierBaseName, // in
+ UINT32 verifierNonceLength, // in
+ BYTE* verifierNonce, // in
+ TSS_DAA_SIGN_DATA signData, // in
+ TSS_DAA_SIGNATURE* daaSignature // out
+)
+{
+ TCS_CONTEXT_HANDLE tcsContext;
+ TSS_DAA_CREDENTIAL *daaCredential;
+ TPM_DAA_ISSUER *tpm_daa_issuer;
+ TPM_AUTH ownerAuth;
+ TSS_RESULT result = TSS_SUCCESS;
+ TSS_DAA_PK *pk;
+ TSS_DAA_PK_internal *pk_intern;
+ int i;
+ bi_ptr tmp1 = bi_new_ptr(), tmp2;
+ bi_ptr n = NULL;
+ bi_ptr capital_gamma = NULL;
+ bi_ptr gamma = NULL;
+ bi_ptr zeta = NULL;
+ bi_ptr r = NULL;
+ bi_ptr t_tilde_T = NULL;
+ bi_ptr capital_Nv = NULL;
+ bi_ptr capital_N_tilde_v = NULL;
+ bi_ptr w = NULL;
+ bi_ptr capital_T = NULL;
+ bi_ptr r_E = NULL;
+ bi_ptr r_V = NULL;
+ bi_ptr capital_T_tilde = NULL;
+ bi_ptr capital_A = NULL;
+ bi_array_ptr capital_R;
+ bi_ptr product_R = NULL;
+ bi_array_ptr r_A = NULL;
+ bi_array_ptr s_A = NULL;
+ bi_ptr c = NULL;
+ bi_ptr sF0 = NULL;
+ bi_ptr sF1 = NULL;
+ bi_ptr sV1 = NULL;
+ bi_ptr sV2 = NULL;
+ bi_ptr e = NULL;
+ bi_ptr s_E = NULL;
+ bi_ptr s_V = NULL;
+ CS_ENCRYPTION_RESULT_RANDOMNESS *encryption_result_rand = NULL;
+ BYTE *issuer_settings = NULL, *outputData, byte;
+ BYTE *buffer = NULL, *ch = NULL, *nonce_tpm = NULL, *c_bytes = NULL;
+ UINT32 issuer_settingsLength, outputSize, length, size_bits, chLength;
+ UINT32 nonce_tpmLength;
+ UINT32 c_bytesLength, return_sign_session;
+ // for anonymity revocation
+ CS_ENCRYPTION_RESULT *encryption_result = NULL;
+ CS_ENCRYPTION_RESULT *encryption_result_tilde = NULL;
+ TSS_DAA_PSEUDONYM *signature_pseudonym;
+ TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain = NULL;
+ TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain_tilde = NULL;
+ TSS_DAA_ATTRIB_COMMIT *signed_commitments;
+
+ if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS)
+ return result;
+ if( tmp1 == NULL) {
+ LogError("malloc of bi <%s> failed", "tmp1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ obj_daa_set_handle_tpm( hDAA, hTPM);
+ // TODO retrieve the daaCredential from the persistence storage
+ daaCredential = (TSS_DAA_CREDENTIAL *)hDaaCredential;
+ pk = (TSS_DAA_PK *)&(daaCredential->issuerPK);
+ pk_intern = e_2_i_TSS_DAA_PK( pk);
+ if( pk_intern == NULL) {
+ LogError("malloc of <%s> failed", "pk_intern");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ tpm_daa_issuer = convert2issuer_settings( pk_intern);
+ if( daaCredential->attributesLength == 0 ||
+ daaCredential->attributesLength != revealAttributes.indicesListLength) {
+ LogDebug("Problem with the reveal attribs: attributes length:%d reveal length:%d",
+ daaCredential->attributesLength, revealAttributes.indicesListLength);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ if( verifierNonce == NULL ||
+ verifierNonceLength != DAA_PARAM_LENGTH_MESSAGE_DIGEST) {
+ LogDebug("Problem with the nonce verifier: nonce verifier length:%d",
+ verifierNonceLength);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ n = bi_new_ptr();
+ if( n == NULL) {
+ LogError("malloc of bi <%s> failed", "n");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( n, pk_intern->modulus);
+ capital_gamma = bi_new_ptr();
+ if( capital_gamma == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_gamma");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( capital_gamma, pk_intern->capitalGamma);
+ gamma = bi_new_ptr();
+ if( gamma == NULL) {
+ LogError("malloc of bi <%s> failed", "gamma");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( gamma, pk_intern->gamma);
+ if( verifierBaseNameLength == 0 || verifierBaseName == NULL) {
+ r = bi_new_ptr();
+ compute_random_number( r, capital_gamma);
+ zeta = project_into_group_gamma( r, pk_intern); // allocation
+ if( zeta == NULL) {
+ LogError("malloc of bi <%s> failed", "zeta");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ } else {
+ zeta = compute_zeta( verifierBaseNameLength, verifierBaseName, pk_intern);
+ if( zeta == NULL) {
+ LogError("malloc of bi <%s> failed", "zeta");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ }
+ issuer_settings = issuer_2_byte_array( tpm_daa_issuer,
+ &issuer_settingsLength); // allocation
+ if( issuer_settings == NULL) {
+ LogError("malloc of %d bytes failed", issuer_settingsLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ LogDebug( "Issuer Settings:[%s]",
+ dump_byte_array(issuer_settingsLength, issuer_settings) );
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 0,
+ issuer_settingsLength, issuer_settings,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ // set the sessionHandle to the returned value
+ return_sign_session = ntohl( *((UINT32 *)outputData));
+ obj_daa_set_session_handle( hDAA, return_sign_session);
+ free( outputData);
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 1,
+ daaCredential->tpmSpecificEncLength, daaCredential->tpmSpecificEnc,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ free( outputData);
+ LogDebug( "done Sign 1 - TPM specific");
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 2,
+ pk->capitalR0Length, pk->capitalR0,
+ pk->modulusLength, pk->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ free( outputData);
+ LogDebug( "done Sign 2 - capitalR0");
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 3,
+ pk->capitalR1Length, pk->capitalR1,
+ pk->modulusLength, pk->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ free( outputData);
+ LogDebug( "done Sign 3 - capitalR1");
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 4,
+ pk->capitalSLength, pk->capitalS,
+ pk->modulusLength, pk->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ if( outputSize > 0 && outputData != NULL) free( outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 4 - capitalS");
+ buffer = bi_2_nbin( &length, pk_intern->capitalSprime); // allocation
+ if( buffer == NULL) {
+ LogError("malloc of %d bytes failed", length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 5,
+ length, buffer,
+ pk->modulusLength, pk->modulus,
+ &ownerAuth, &outputSize, &outputData);
+ free( buffer);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 5 - capitalSPrime. Return t_tilde_T");
+ t_tilde_T = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( t_tilde_T == NULL) {
+ LogError("malloc of bi <%s> failed", "t_tilde_T");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ // first precomputation until here possible (verifier independent)
+ length = TPM_DAA_SIZE_w;
+ buffer = (BYTE *)malloc( length);
+ if( buffer == NULL) {
+ LogError("malloc of %d bytes failed", length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_byte_array( buffer, length, zeta);
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 6,
+ pk->capitalGammaLength, pk->capitalGamma,
+ length, buffer,
+ &ownerAuth, &outputSize, &outputData);
+ free( buffer);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 6 - capitalGamma & zeta");
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 7,
+ pk->capitalGammaLength, pk->capitalGamma,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 7 - capitalGamma. Return capital_Nv");
+ capital_Nv = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( capital_Nv == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_Nv");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ // TODO Step 6 a.b - anonymity revocation
+
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 8,
+ pk->capitalGammaLength, pk->capitalGamma,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 8 - capitalGamma. Return capital_N_tilde_v");
+ capital_N_tilde_v = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( capital_N_tilde_v == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_N_tilde_v");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ // TODO Step 6 c,d - anonymity revocation
+
+ // Second precomputation until here possible (verifier dependent)
+ size_bits = DAA_PARAM_SIZE_RSA_MODULUS + DAA_PARAM_SAFETY_MARGIN;
+ w = bi_new_ptr();
+ if( w == NULL) {
+ LogError("malloc of bi <%s> failed", "w");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_urandom( w, size_bits);
+ capital_A = bi_set_as_nbin( daaCredential->capitalALength,
+ daaCredential->capitalA); // allocation
+ if( capital_A == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_A");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capital_T = bi_new_ptr();
+ if( capital_T == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_T");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( tmp1, pk_intern->capitalS, w, n);
+ bi_mul( capital_T, capital_A, tmp1);
+ bi_mod( capital_T, capital_T, n);
+ size_bits = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE +
+ DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST;
+ r_E = bi_new_ptr();
+ if( r_E == NULL) {
+ LogError("malloc of bi <%s> failed", "r_E");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_urandom( r_E, size_bits);
+ size_bits = DAA_PARAM_SIZE_EXPONENT_CERTIFICATE + DAA_PARAM_SIZE_RSA_MODULUS +
+ 2 * DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST + 1;
+ r_V = bi_new_ptr();
+ if( r_V == NULL) {
+ LogError("malloc of bi <%s> failed", "r_V");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_urandom( r_V, size_bits);
+ capital_T_tilde = bi_new_ptr();
+ if( capital_T_tilde == NULL) {
+ LogError("malloc of bi <%s> failed", "capital_T_tilde");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mod_exp( tmp1, capital_T, r_E, n);
+ bi_mul( capital_T_tilde, t_tilde_T, tmp1);
+ bi_mod( capital_T_tilde, capital_T_tilde, n);
+
+ bi_mod_exp( tmp1, pk_intern->capitalS, r_V, n);
+ bi_mul( capital_T_tilde, capital_T_tilde, tmp1);
+ bi_mod( capital_T_tilde, capital_T_tilde, n);
+
+ // attributes extension
+ size_bits = DAA_PARAM_SIZE_F_I +
+ DAA_PARAM_SAFETY_MARGIN +
+ DAA_PARAM_SIZE_MESSAGE_DIGEST;
+ capital_R = pk_intern->capitalY;
+ r_A = (bi_array_ptr)malloc( sizeof( struct _bi_array));
+ if( r_A == NULL) {
+ LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_new_array2( r_A, revealAttributes.indicesListLength);
+ product_R = bi_new_ptr();
+ if( product_R == NULL) {
+ LogError("malloc of bi <%s> failed", "product_R");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( product_R, bi_1);
+ for( i=0; i<(int)revealAttributes.indicesListLength; i++) {
+ if( revealAttributes.indicesList[i] == 0) {
+ // only non selected
+ r_A->array[i] = bi_new_ptr();
+ if( r_A->array[i] == NULL) {
+ LogError("malloc of bi <%s> failed", "r_A->array[i]");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_urandom( r_A->array[i] , size_bits);
+ bi_mod_exp( tmp1, capital_R->array[i], r_A->array[i], n);
+ bi_mul( product_R, product_R, tmp1);
+ bi_mod( product_R, product_R, n);
+ } else r_A->array[i] = NULL;
+ }
+ bi_mul( capital_T_tilde, capital_T_tilde, product_R);
+ bi_mod( capital_T_tilde, capital_T_tilde, n);
+ //TODO Step 8 - Commitments
+ // compute commitment to attributes not revealed to the verifier
+
+ //TODO Step 9 - callback functions
+
+ // only when revocation not enabled
+ pseudonym_plain = (TSS_DAA_PSEUDONYM_PLAIN *)calloc_tspi( tcsContext,
+ sizeof(TSS_DAA_PSEUDONYM_PLAIN));
+ if( pseudonym_plain == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(TSS_DAA_PSEUDONYM_PLAIN));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ init_tss_version( pseudonym_plain);
+ pseudonym_plain->capitalNv = calloc_tspi( tcsContext,
+ bi_nbin_size( capital_Nv));
+ if( pseudonym_plain->capitalNv == NULL) {
+ LogError("malloc of bi <%s> failed", "pseudonym_plain->capitalNv");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(pseudonym_plain->capitalNvLength),
+ pseudonym_plain->capitalNv,
+ capital_Nv);
+ pseudonym_plain_tilde = (TSS_DAA_PSEUDONYM_PLAIN *)
+ calloc_tspi( tcsContext,sizeof(TSS_DAA_PSEUDONYM_PLAIN));
+ if( pseudonym_plain_tilde == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(TSS_DAA_PSEUDONYM_PLAIN));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ init_tss_version( pseudonym_plain_tilde);
+ pseudonym_plain_tilde->capitalNv = calloc_tspi( tcsContext,
+ bi_nbin_size( capital_N_tilde_v));
+ if( pseudonym_plain_tilde->capitalNv == NULL) {
+ LogError("malloc of bi <%s> failed", "pseudonym_plain_tilde->capitalNv");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(pseudonym_plain_tilde->capitalNvLength),
+ pseudonym_plain_tilde->capitalNv,
+ capital_N_tilde_v);
+
+ // Step 10 - compute challenge
+ ch = compute_sign_challenge_host(
+ &chLength,
+ DAA_PARAM_get_message_digest(),
+ pk_intern,
+ verifierNonceLength,
+ verifierNonce,
+ 0, // int selected_attributes2commitLength,
+ NULL, // TSS_DAA_SELECTED_ATTRIB **selected_attributes2commit,
+ 0, // int is_anonymity_revocation_enabled,
+ zeta,
+ capital_T,
+ capital_T_tilde,
+ 0, // int attribute_commitmentsLength,
+ NULL, // TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitments,
+ NULL, // TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitment_proofs,
+ capital_Nv,
+ capital_N_tilde_v,
+ NULL, // CS_PUBLIC_KEY *anonymity_revocator_pk,
+ NULL, // CS_ENCRYPTION_RESULT *encryption_result_rand,
+ NULL //CS_ENCRYPTION_RESULT *encryption_result_proof)
+ );
+ if( ch == NULL) {
+ LogError("malloc in compute_sign_challenge_host failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ result = Tcsip_TPM_DAA_Sign( tcsContext, hDAA,
+ 9,
+ chLength, ch,
+ 0, NULL,
+ &ownerAuth, &nonce_tpmLength, &nonce_tpm);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 9 - compute sign challenge host. Return nonce_tpm");
+ byte = (BYTE)signData.payloadFlag; // 0 -> payload contains a handle to an AIK
+ // 1 -> payload contains a hashed message
+ result = Tcsip_TPM_DAA_Sign( tcsContext, hDAA,
+ 10,
+ sizeof(BYTE), &byte,
+ signData.payloadLength, signData.payload,
+ &ownerAuth, &c_bytesLength, &c_bytes);
+ LogDebug("calculation of c: ch[%d]%s", chLength, dump_byte_array( chLength, ch));
+ LogDebug("calculation of c: nonce_tpm[%d]%s",
+ nonce_tpmLength,
+ dump_byte_array( nonce_tpmLength, nonce_tpm));
+ LogDebug("calculation of c: sign_data.payloadFlag[%d]%x",
+ 1,
+ (int)signData.payloadFlag);
+ LogDebug("calculation of c: signdata.payload[%d]%s",
+ signData.payloadLength,
+ dump_byte_array( signData.payloadLength, signData.payload));
+
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 10 - compute signData.payload.");
+ LogDebug(" Return c_bytes[%d]%s",
+ c_bytesLength,
+ dump_byte_array( c_bytesLength, c_bytes));
+ c = bi_set_as_nbin( c_bytesLength, c_bytes); // allocation
+ if( c == NULL) {
+ LogError("malloc of bi <%s> failed", "c");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 11,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS)goto close;
+ LogDebug( "done Sign 11. Return sF0");
+ sF0 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( sF0 == NULL) {
+ LogError("malloc of bi <%s> failed", "sF0");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 12,
+ 0, NULL,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 12. Return sF1");
+ sF1 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( sF1 == NULL) {
+ LogError("malloc of bi <%s> failed", "sF1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 13,
+ daaCredential->vBar0Length, daaCredential->vBar0,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 13. Return sV1");
+ sV1 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( sV1 == NULL) {
+ LogError("malloc of bi <%s> failed", "sV1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 14,
+ daaCredential->vBar0Length, daaCredential->vBar0,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ free( outputData);
+ LogDebug( "done Sign 14.");
+ result = Tcsip_TPM_DAA_Sign(
+ tcsContext, hDAA,
+ 15,
+ daaCredential->vBar1Length, daaCredential->vBar1,
+ 0, NULL,
+ &ownerAuth, &outputSize, &outputData);
+ if( result != TSS_SUCCESS) goto close;
+ LogDebug( "done Sign 15. Return sV2");
+ sV2 = bi_set_as_nbin( outputSize, outputData); // allocation
+ if( sV2 == NULL) {
+ LogError("malloc of bi <%s> failed", "sV2");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ free( outputData);
+ // allocation
+ e = bi_set_as_nbin( daaCredential->exponentLength, daaCredential->exponent);
+ if( e == NULL) {
+ LogError("malloc of bi <%s> failed", "e");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // s_e = r_E + ( c * ( e - ( 1 << (sizeExponentCertificate -1))))
+ s_E = bi_new_ptr();
+ if( s_E == NULL) {
+ LogError("malloc of bi <%s> failed", "s_E");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1);
+ bi_sub( tmp1, e, tmp1);
+ bi_mul( tmp1, c, tmp1);
+ bi_add( s_E, r_E, tmp1);
+ s_V = bi_new_ptr();
+ if( s_V == NULL) {
+ LogError("malloc of bi <%s> failed", "s_V");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ add_splitet( s_V, sV1, sV2);
+ bi_add( s_V, s_V, r_V);
+ bi_mul( tmp1, c, w);
+ bi_mul( tmp1, tmp1, e);
+ bi_sub( s_V, s_V, tmp1);
+ // attributes extension
+ // TODO verify the size of each selected attributes
+ s_A = (bi_array_ptr)malloc( sizeof( struct _bi_array));
+ if( s_A == NULL) {
+ LogError("malloc of bi_array <%s> failed", "s_A");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_new_array2( s_A, revealAttributes.indicesListLength);
+ if( s_A->array == NULL) {
+ LogError("malloc of bi_array <%s> failed", "s_A");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( i=0; i<(int)revealAttributes.indicesListLength; i++) {
+ if( revealAttributes.indicesList[i] == 0) {
+ s_A->array[i] = bi_new_ptr();
+ if( s_A->array[i] == NULL) {
+ LogError("malloc of bi <%s> failed", "s_A->array[i]");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ tmp2 = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
+ daaCredential->attributes[i]); // allocation
+ if( tmp2 == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_mul( tmp1, c, tmp2);
+ // TODEL
+ LogDebug("daaCredential->attributes[i]=%ld", bi_nbin_size( tmp2));
+ LogDebug("r_A:%ld", bi_nbin_size( r_A->array[i]));
+ LogDebug("c:%ld", bi_nbin_size( c));
+ LogDebug("c*daaCredential->attributes[i]=%ld", bi_nbin_size( tmp1));
+ // END TODEL
+ bi_add( s_A->array[i], r_A->array[i], tmp1);
+ bi_free_ptr( tmp2);
+ } else s_A->array[i] = NULL;
+ }
+
+ // Compose result structure
+
+ // DAASignaturePseudonym TODO: implement anonymity revocation
+ // if ( !revocation_enabled)
+ signature_pseudonym = pseudonym_plain;
+
+ // populate the signature (TSS_DAA_SIGNATURE)
+ daaSignature->zeta = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( zeta));
+ if (daaSignature->zeta == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( zeta));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaSignature->zetaLength), daaSignature->zeta, zeta);
+ daaSignature->capitalT = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( capital_T));
+ if (daaSignature->capitalT == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( capital_T));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaSignature->capitalTLength), daaSignature->capitalT, capital_T);
+ daaSignature->challenge = (BYTE *)calloc_tspi( tcsContext, c_bytesLength);
+ if (daaSignature->challenge == NULL) {
+ LogError("malloc of %d bytes failed", c_bytesLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ daaSignature->challengeLength = c_bytesLength;
+ memcpy( daaSignature->challenge, c_bytes, c_bytesLength);
+ daaSignature->nonceTpm = (BYTE *)calloc_tspi( tcsContext, nonce_tpmLength);
+ if (daaSignature->nonceTpm == NULL) {
+ LogError("malloc of %d bytes failed", nonce_tpmLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ daaSignature->nonceTpmLength = nonce_tpmLength;
+ memcpy( daaSignature->nonceTpm, nonce_tpm, nonce_tpmLength);
+ daaSignature->sV = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( s_V));
+ if (daaSignature->sV == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( s_V));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaSignature->sVLength), daaSignature->sV, s_V);
+ daaSignature->sF0 = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( sF0));
+ if (daaSignature->sF0 == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( sF0));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaSignature->sF0Length), daaSignature->sF0, sF0);
+ daaSignature->sF1 = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( sF1));
+ if (daaSignature->sF1 == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( sF1));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaSignature->sF1Length), daaSignature->sF1, sF1);
+ daaSignature->sE = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( s_E));
+ if (daaSignature->sE == NULL) {
+ LogError("malloc of %ld bytes failed", bi_nbin_size( s_E));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_2_nbin1( &(daaSignature->sELength), daaSignature->sE, s_E);
+ daaSignature->sALength = revealAttributes.indicesListLength;
+ daaSignature->sA = (BYTE **)calloc_tspi(
+ tcsContext,
+ sizeof(BYTE *)*revealAttributes.indicesListLength);
+ if (daaSignature->sA == NULL) {
+ LogError("malloc of %d bytes failed",
+ sizeof(BYTE *)*revealAttributes.indicesListLength);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ length = (DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8;
+ for( i=0; i<(int)revealAttributes.indicesListLength; i++) {
+ daaSignature->sA[i] = calloc_tspi( tcsContext, length);
+ if (daaSignature->sA[i] == NULL) {
+ LogError("malloc of %d bytes failed", length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ if( s_A->array[i] == NULL)
+ bi_2_byte_array( daaSignature->sA[i], length, bi_0);
+ else {
+ bi_2_byte_array( daaSignature->sA[i], length, s_A->array[i]);
+ LogDebug("size big_integer s_A[i] = %ld size daaSignature->sA[i]=%d",
+ bi_nbin_size( s_A->array[i]), length);
+ }
+ }
+ daaSignature->attributeCommitmentsLength = 0;
+ daaSignature->signedPseudonym = signature_pseudonym;
+close:
+ bi_free_ptr( tmp1);
+ if( c_bytes != NULL) free( c_bytes);
+ if( ch != NULL) free( ch);
+ if( nonce_tpm != NULL) free( nonce_tpm);
+ if( encryption_result !=NULL) free( encryption_result);
+ if( encryption_result_tilde !=NULL) free( encryption_result_tilde);
+ if( issuer_settings != NULL) free( issuer_settings);
+ if( r_A != NULL) {
+ for( i=0; i<(int)revealAttributes.indicesListLength; i++)
+ if( r_A->array[i] != NULL) bi_free_ptr( r_A->array[i]);
+ free( r_A);
+ }
+ FREE_BI( s_V);
+ FREE_BI( s_E);
+ FREE_BI( e);
+ FREE_BI( sV2);
+ FREE_BI( sV1);
+ FREE_BI( sF1);
+ FREE_BI( sF0);
+ FREE_BI( c);
+ FREE_BI( product_R);
+ FREE_BI( capital_A);
+ FREE_BI( capital_T_tilde);
+ FREE_BI( r_V);
+ FREE_BI( r_E);
+ FREE_BI( capital_T);
+ FREE_BI( w);
+ FREE_BI( capital_N_tilde_v);
+ FREE_BI( capital_Nv);
+ FREE_BI( t_tilde_T);
+ FREE_BI( n);
+ FREE_BI( capital_gamma);
+ FREE_BI( gamma);
+ FREE_BI( zeta);
+ FREE_BI( r);
+ free_TSS_DAA_PK_internal( pk_intern);
+ free_TPM_DAA_ISSUER( tpm_daa_issuer);
+ return result;
+}
diff --git a/src/tspi/daa/daa_platform/test.c b/src/tspi/daa/daa_platform/test.c
new file mode 100644
index 0000000..04fdd38
--- /dev/null
+++ b/src/tspi/daa/daa_platform/test.c
@@ -0,0 +1,142 @@
+
+#include <stdlib.h>
+#include <string.h>
+#include <trousers/tss.h>
+#include <trousers/trousers.h>
+#include "spi_internal_types.h"
+#include <spi_utils.h>
+#include <obj.h>
+#include "tsplog.h"
+#include "daa_parameter.h"
+
+setenv("TCSD_FOREGROUND", "1", 1);
+
+// simulating Tspi_TPM_DAA_JoinInit (spi_daa.c)
+TSS_RESULT Tspi_DAA_Join(TSS_HTPM hTPM, int stage, UINT32 inputSize0, BYTE *inputData0, UINT32 inputSize1, BYTE *inputData1, UINT32 *outputSize, BYTE **outputData) {
+ TSS_RESULT result;
+ TCS_CONTEXT_HANDLE tcsContext;
+ TSS_HCONTEXT tspContext;
+ TSS_HPOLICY hPolicy;
+ TCPA_DIGEST digest;
+ TPM_AUTH ownerAuth;
+ UINT16 offset = 0;
+ BYTE hashblob[1000];
+
+ printf("[%s:%d] obj_tpm_is_connected(hTPM)\n", __FILE__, __LINE__);
+ if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) return result;
+ printf("[%s:%d] obj_tpm_get_tsp_context(hTPM)\n", __FILE__, __LINE__);
+ if( (result = obj_tpm_get_tsp_context( hTPM, &tspContext)) != TSS_SUCCESS) return result;
+ printf("[%s:%d] obj_tpm_get_policy(hTPM)\n", __FILE__, __LINE__);
+ if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS) return result;
+
+ printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob)\n", __FILE__, __LINE__);
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob); // hash TPM_COMMAND_CODE
+ printf("[%s:%d] Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)\n",__FILE__, __LINE__);
+ Trspi_LoadBlob_BYTE(&offset, stage, hashblob); // hash stage
+ printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, 0, hashblob)\n",__FILE__, __LINE__);
+ //TODO old 4
+ Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob); // hash inputSize0
+ printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, 0, hashblob)\n",__FILE__, __LINE__);
+ Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0); // hash inputData0
+ //TODO old 1
+ Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob); // hash inputSize1
+ printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, 0, hashblob)\n",__FILE__, __LINE__);
+ Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1); // hash inputData1
+ Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
+
+ if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join,
+ hPolicy, &digest,
+ &ownerAuth)) != TSS_SUCCESS) return result;
+ printf("[%s:%d] secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d\n",__FILE__, __LINE__, result);
+ // out
+
+ /* step of the following call:
+ TCSP_DAAJoin tcsd_api/calltcsapi.c (define in spi_utils.h)
+ TCSP_DAAJoin_TP tcsd_api/tcstp.c (define in trctp.h)
+ */
+
+ printf("[%s:%d] TCSP_DAAJoin(%x,%x,%x,%x,%x,%x,%x)\n",__FILE__, __LINE__,
+ (int)hTPM, 0, inputSize0,(int)inputData0,inputSize1,(int)inputData1,(int)&ownerAuth);
+ if ( (result = TCSP_DaaJoin( tcsContext, hTPM, 0, inputSize0, inputData0, inputSize1, inputData1, &ownerAuth, outputSize, outputData)) != TSS_SUCCESS)
+ return result;
+
+ offset = 0;
+ Trspi_LoadBlob_UINT32(&offset, result, hashblob);
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob);
+ Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob);
+ Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData);
+ Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
+ if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, &ownerAuth)))
+ {
+ printf("[%s:%d] obj_policy_validate_auth=%d\n",__FILE__, __LINE__, result);
+ }
+ return result;
+}
+
+
+int main(int argc, char *argv[])
+{
+ TSS_HCONTEXT hContext;
+ TSS_RESULT result;
+ TSS_HTPM hTPM;
+ TSS_HPOLICY hPolicy;
+
+ // Create Context
+ printf("Create Context\n");
+ result = Tspi_Context_Create( &hContext );
+ if ( result != TSS_SUCCESS )
+ {
+ fprintf( stderr, "Tspi_Context_Create %d\n", result );
+ exit( result );
+ }
+
+ // Connect to Context
+ printf("\nConnect to the context\n");
+ result = Tspi_Context_Connect( hContext, NULL );
+ if ( result != TSS_SUCCESS ) goto out_close;
+
+ if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS)
+ goto out_close;
+
+ // Get the correct policy using the TPM ownership PASSWD
+ char *szTpmPasswd = "OWN_PWD";
+ if( (result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hPolicy)) != TSS_SUCCESS)
+ goto out_close;
+ //BUSS
+ if( (result = Tspi_Policy_SetSecret( hPolicy, TSS_SECRET_MODE_PLAIN, strlen( szTpmPasswd), szTpmPasswd)) != TSS_SUCCESS)
+ goto out_close;
+ printf("Tspi_Policy_SetSecret hPolicy received;%d\n", hPolicy);
+
+ //BUSS
+ // in
+ //int modulus_length = DAA_PARAM_SIZE_MODULUS_GAMMA / 8;
+ UINT32 inputSize0 = sizeof(int);
+ UINT32 inputSize1 = 0;
+ UINT32 outputSize = 0;
+ int ia_length = 7;
+ BYTE *inputData0 = (BYTE *)(&ia_length);//= (BYTE *)malloc( inputSize0)
+ BYTE *inputData1 = NULL;
+ BYTE *outputData = NULL;
+
+ if( (result = Tspi_DAA_Join(hTPM, 0, inputSize0, inputData0, inputSize1, inputData1, &outputSize, &outputData)) != TSS_SUCCESS) goto out_close;
+
+ goto out;
+out_close:
+ printf( "Tspi Error:%d - %s\n", result, err_string( result) );
+
+out:
+ printf("ouputSize=%d\n", outputSize);
+ if( outputData != NULL) {
+ int i;
+ printf("outputData(hex )=[\n");
+ for( i=0; i<(int)outputSize; i++) printf("%x ", outputData[i]);
+ printf("\n]");
+ printf("outputData(ascii)=[\n");
+ for( i=0; i<(int)outputSize; i++) printf("%c ", outputData[i]);
+ printf("\n]");
+ }
+ Tspi_Context_FreeMemory( hContext, NULL );
+ Tspi_Context_Close( hContext );
+ printf("[%s:%d] THE END\n",__FILE__, __LINE__);
+ return result;
+}
diff --git a/src/tspi/daa/daa_platform/test_join.c b/src/tspi/daa/daa_platform/test_join.c
new file mode 100644
index 0000000..a244d85
--- /dev/null
+++ b/src/tspi/daa/daa_platform/test_join.c
@@ -0,0 +1,504 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "daa_structs.h"
+#include "trousers/tss.h"
+#include "trousers/trousers.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include "obj.h"
+#include "tsplog.h"
+#include "daa_parameter.h"
+#include "verifier.h"
+#include "platform.h"
+
+// for RSA Key
+#include <openssl/rsa.h>
+
+#define DEFAULT_FILENAME "issuer.txt"
+#define DEFAULT_CREDENTIAL_FILENAME "credential.txt"
+#define DEFAULT_DAACOUNTER 0x01020304
+#define DEFAULT_OWN_PASSWD "OWN_PWD"
+
+// from IssuerFactory
+static const int DEFAULT_KEY_CHAIN_LENGTH = 3;
+
+typedef struct tdIssuer {
+ // use on Tspi calls
+ TSS_DAA_PK *pk_extern;
+ TSS_DAA_KEY_PAIR *key_pair_extern;
+
+ // used internally
+ int length_key_chain;
+ RSA **key_chain;
+ TSS_DAA_PK_internal *pk;
+ DAA_PRIVATE_KEY_internal *private_key;
+ TSS_DAA_PK_PROOF_internal *pk_proof;
+ //RSA **auth_key_pairs;
+ BYTE **pk_signatures;
+ bi_ptr zeta;
+} Issuer;
+
+void *alloc( UINT32 length, TCS_CONTEXT_HANDLE tcsContext) {
+ void *result = calloc_tspi( tcsContext, length);
+ LogDebug("allocate tspi memory:%d", (int)result);
+ return result;
+}
+
+/**
+Used by RSA_generate_key
+From RSA_generate_key documentation:
+-> callback(2, n, cb_arg) is called when n-th randomly generated prime is rejected
+-> callback(3, 0, cb_arg) is called when p is found with p-1 more or less prime to e
+-> callback(3, 1, cb_arg) repeatedly called for prime q
+*/
+void callback(int step, int number, void *arg) {
+#ifdef DAA_DEBUG
+ putc( '.', stdout); fflush( stdout);
+#endif
+}
+
+int sign( BYTE *buffer_2_sign,
+ int len_buffer_2_sign,
+ RSA *rsa,
+ BYTE *signature,
+ int *len_signature
+) {
+ EVP_MD_CTX ctx;
+ int len_message = EVP_MD_size( EVP_sha1()), current_len_message;
+ BYTE *message = (BYTE *)malloc( len_message);
+ int ret;
+
+ EVP_MD_CTX_init(&ctx);
+ EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctx, buffer_2_sign, len_buffer_2_sign);
+ EVP_DigestFinal_ex(&ctx, message, &current_len_message);
+ LogDebug("Sign rsa-> with message (length=%d)", current_len_message);
+// int RSA_sign(int type, unsigned char *m, unsigned int m_len,
+// unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+ ret = RSA_sign( NID_sha1, message, current_len_message, signature, len_signature, rsa);
+ if( ret == 0) {
+ LogError("Error in RSA_sign: %s", ERR_error_string( ERR_get_error(), NULL));
+ }
+ LogDebug("Sign rsa-> signature (length=%d)", *len_signature );
+ EVP_MD_CTX_cleanup(&ctx);
+ free( message);
+ return ret;
+}
+
+/* Compute key chain. */
+static int init_key_chain(int length_key_chain, Issuer *issuer) {
+ BYTE *signature;
+ int i, len_sign, ret;
+ BYTE *modulus;
+ BYTE *message;
+ // generate RSA key of length DAA_PARAM_KEY_SIZE with exponent
+ // 65537 (java.security.spec.RSAKeyGenParameterSpec.F4)
+ unsigned long e = 65537;
+ RSA *rsa;
+ bi_ptr bi;
+ EVP_MD_CTX ctx;
+ int len_message = EVP_MD_size( EVP_sha1());
+ int current_len_message;
+
+ EVP_MD_CTX_init(&ctx);
+ message = (BYTE *)malloc(len_message);
+ if( length_key_chain < 1) {
+ free( message);
+ return -1;
+ }
+ issuer->length_key_chain = length_key_chain;
+ issuer->key_chain = (RSA **)malloc(sizeof(RSA *) * length_key_chain);
+ issuer->pk_signatures = (BYTE **)malloc(sizeof(BYTE *) * length_key_chain);
+ for(i = 0; i<length_key_chain; i++) {
+ rsa = RSA_generate_key( DAA_PARAM_KEY_SIZE, e, &callback, NULL);
+ if( (BN_num_bits(rsa->n) + 7) / 8 != (DAA_PARAM_KEY_SIZE + 7) / 8) {
+ LogError("BN_num_bits(rsa->n) + 7) / 8 != (DAA_PARAM_KEY_SIZE + 7) / 8)");
+ return -1;
+ }
+ issuer->key_chain[i] = rsa;
+ if( i > 0) {
+ signature = (BYTE *)malloc( RSA_size(rsa));
+ modulus = (BYTE *)malloc( DAA_PARAM_KEY_SIZE / 8);
+ // signature algorithm from Issuer.java - "SHA1withRSA"
+ // sign the modulus (n) of the RSA key with the previous RSA key (chain)
+ // sign rsa(i)->n with auth_key_pairs[i-1]
+ LogDebug("modulus=%s\n", dump_byte_array(256, modulus));
+ LogDebug("signature=%s\n", dump_byte_array(256, signature));
+ bi = bi_new_ptr();
+ bi_set_as_hex( bi, BN_bn2hex( rsa->n));
+ bi_2_byte_array( modulus, DAA_PARAM_KEY_SIZE / 8, bi);
+ LogDebug("bi=%s", bi_2_hex_char( bi));
+ bi_free_ptr( bi);
+ EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctx, modulus, DAA_PARAM_KEY_SIZE / 8);
+ EVP_DigestFinal_ex(&ctx, message, &current_len_message);
+ ret = RSA_sign( NID_sha1, message, current_len_message,
+ signature, &len_sign, issuer->key_chain[i-1]);
+ if( ret == 0) {
+ LogError("Error in RSA_sign: %s",
+ ERR_error_string( ERR_get_error(), NULL));
+ }
+ LogDebug("Sign rsa->n (length=%d) with signature (length=%d,\
+ truelength=%d message_len=%d) ret = %d ERROR?=%s",
+ RSA_size(rsa),
+ DAA_PARAM_KEY_SIZE / 8,
+ len_sign,
+ current_len_message,
+ ret,
+ ERR_error_string( ERR_get_error(),
+ NULL) );
+ LogDebug("message=%s\n", dump_byte_array(256, message));
+ LogDebug("signature=%s\n",dump_byte_array(256, signature));
+ issuer->pk_signatures[i-1] = signature;
+ }
+ }
+ free( message);
+ EVP_MD_CTX_cleanup(&ctx);
+ return 0;
+}
+
+Issuer* initIssuer(int length_key_chain, char *filename, char *exec, TSS_HCONTEXT hContext) {
+ FILE *file;
+ EVP_MD_CTX mdctx;
+ Issuer *issuer = (Issuer *)malloc(sizeof( Issuer));
+ TPM_DAA_ISSUER *tpm_daa_issuer;
+ bi_ptr modulus_N0;
+ int len_issuer_settings, len_signature;
+ BYTE *modulus_N0_bytes;
+ BYTE *digest_n0;
+ BYTE *issuer_settings_byte_array;
+ BYTE *sign_data;
+ BYTE *signature;
+ RSA *private_nn;
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof;
+
+ LogDebug("Loading issuer info (keypair & proof) -> \'%s\'", filename);
+ file = fopen( filename, "r");
+ if( file == NULL) {
+ fprintf( stderr, "%s: Error when opening \'%s\': %s\n",
+ exec,
+ filename,
+ strerror( errno));
+ free( issuer);
+ return NULL;
+ }
+ key_pair_with_proof = load_KEY_PAIR_WITH_PROOF( file);
+ if( key_pair_with_proof == NULL) {
+ LogError( "Error when reading \'%s\': %s\n", filename, strerror( errno));
+ free( issuer);
+ return NULL;
+ }
+ fclose( file);
+ issuer->pk = key_pair_with_proof->pk;
+ issuer->pk_extern = i_2_e_TSS_DAA_PK( issuer->pk, &alloc, hContext);
+ issuer->key_pair_extern = (TSS_DAA_KEY_PAIR *)malloc( sizeof(TSS_DAA_KEY_PAIR));
+ init_tss_version( issuer->key_pair_extern);
+ issuer->key_pair_extern->public_key = issuer->pk_extern;
+ issuer->key_pair_extern->private_key = i_2_e_TSS_DAA_PRIVATE_KEY(
+ key_pair_with_proof->private_key,
+ &alloc, hContext);
+ issuer->pk_proof = key_pair_with_proof->proof;
+ issuer->private_key = key_pair_with_proof->private_key;
+ init_key_chain( length_key_chain, issuer);
+ issuer->zeta = compute_zeta( issuer->pk->issuerBaseNameLength,
+ issuer->pk->issuerBaseName, issuer->pk);
+ // sign "issuer settings"
+ modulus_N0 = bi_new_ptr();
+ bi_set_as_hex( modulus_N0, BN_bn2hex( issuer->key_chain[0]->n));
+ // in TPM, N0 is hashed by hashing the scratch (256 bytes) so it must
+ // be formatted according to the scratch size (TPM_DAA_SIZE_issuerModulus)
+ modulus_N0_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus);
+ bi_2_byte_array( modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus, modulus_N0);
+ bi_free_ptr( modulus_N0);
+
+ if( TPM_DAA_SIZE_issuerModulus * 8 != DAA_PARAM_KEY_SIZE) {
+ LogError("TPM_DAA_SIZE_issuerModulus * 8 (%d) != DAA_PARAM_KEY_SIZE(%d)",
+ TPM_DAA_SIZE_issuerModulus*8,
+ DAA_PARAM_KEY_SIZE);
+ free( issuer);
+ return NULL;
+ }
+
+ EVP_MD_CTX_init(&mdctx);
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ // digestN0 = hash( modulus_N0)
+ EVP_DigestUpdate(&mdctx, modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus);
+ digest_n0 = (BYTE *)malloc( EVP_MD_CTX_size(&mdctx));
+ EVP_DigestFinal_ex(&mdctx, digest_n0, NULL);
+ tpm_daa_issuer = convert2issuer_settings( issuer->pk);
+ issuer_settings_byte_array = issuer_2_byte_array( tpm_daa_issuer, &len_issuer_settings);
+ // data to sign: concatenation of digest_n0 and issuer_settings_byte_array
+ sign_data = (BYTE *)malloc( EVP_MD_CTX_size(&mdctx) + len_issuer_settings);
+ memcpy( sign_data, digest_n0, EVP_MD_CTX_size(&mdctx));
+ memcpy( &sign_data[EVP_MD_CTX_size(&mdctx)],
+ issuer_settings_byte_array,
+ len_issuer_settings);
+ free( issuer_settings_byte_array);
+ // sign digest of TPM compatible Issuer key (sign_data)
+ private_nn = issuer->key_chain[issuer->length_key_chain - 1];
+ signature = (BYTE *)malloc( RSA_size(private_nn));
+ if ( sign( sign_data, EVP_MD_CTX_size(&mdctx) + len_issuer_settings,
+ private_nn,
+ signature,
+ &len_signature) ==0) {
+ LogError("Can not sign digest of TPM compatible Issuer key");
+ goto close;
+ }
+ issuer->pk_signatures[ issuer->length_key_chain - 1] = signature;
+ LogDebug("Set last signature sign[%d] = %s",
+ issuer->length_key_chain - 1,
+ dump_byte_array(EVP_MD_size( EVP_sha1()),
+ signature));
+ // TODO sign the complete public key of TPM compatible Issuer key
+/* EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ EVP_DigestUpdate(&mdctx, digest_n0, EVP_MD_CTX_size(&mdctx));
+ pk_encoded = encoded_DAA_PK_internal( &pk_encodedLength, issuer->pk);
+ EVP_DigestUpdate(&mdctx, pk_encoded, pk_encodedLength);
+ EVP_DigestFinal(&mdctx, , NULL);
+ signature = (BYTE *)malloc( EVP_MD_size( EVP_sha1()));
+ if (sign( sign_data, EVP_MD_CTX_size(&mdctx) + len_issuer_settings,
+ private_nn, signature, &len_signature) !=0) goto close;
+*/
+close:
+ free( digest_n0);
+ free( sign_data);
+ return issuer;
+}
+
+int print_usage(char *exec) {
+ fprintf(stderr, "usage: %s\n", exec);
+ fprintf(stderr, "\t-if,\t--issuer_file\n\t\tthe file that will contain all key\
+pair and proof to be used by the issuer\n\t\t (default: %s)\n",
+ DEFAULT_FILENAME);
+ fprintf(stderr, "\t-dc,\t--daa_counter\n\t\tdaa counter (default: %d)\n",
+ DEFAULT_DAACOUNTER);
+ fprintf(stderr,
+ "\t-pw,\t--passwd\n\t\ttpm owner password (default: %s)\n",
+ DEFAULT_OWN_PASSWD);
+ return -1;
+}
+
+int main(int argc, char *argv[]) {
+ TSS_HCONTEXT hContext;
+ TSS_RESULT result;
+ TSS_HTPM hTPM;
+ TSS_HPOLICY hPolicy;
+ int i, length;
+ char *param, *filename = DEFAULT_FILENAME;
+ char *credential_filename = DEFAULT_CREDENTIAL_FILENAME;
+ UINT32 daaCounter = DEFAULT_DAACOUNTER;
+ UINT32 capital_UPrimeLength;
+ BYTE *capitalUPrime;
+ TSS_DAA_IDENTITY_PROOF identityProof;
+ TSS_DAA_JOIN_SESSION joinSession;
+ TSS_DAA_JOIN_ISSUER_SESSION join_issuer_session;
+ TSS_DAA_CREDENTIAL_REQUEST credentialRequest;
+ TSS_DAA_CRED_ISSUER credIssuer;
+ TSS_HDAA hDAA;
+ Issuer* issuer;
+ char *szTpmPasswd = DEFAULT_OWN_PASSWD;
+ UINT32 endorsementKeyLength;
+ BYTE *endorsementKey;
+ UINT32 nonceIssuerLength;
+ BYTE *nonceIssuer;
+ UINT32 authenticationChallengeLength;
+ BYTE *authenticationChallenge;
+ bi_array_ptr capital_receiver;
+ BYTE **attributesPlatform;
+ UINT32 attributesPlatformLength;
+ BYTE **attributesIssuer;
+ UINT32 attributesIssuerLength;
+ bi_t random;
+ FILE *file;
+
+ init_tss_version( &identityProof);
+ init_tss_version( &joinSession);
+ init_tss_version( &join_issuer_session);
+ init_tss_version( &credentialRequest);
+ init_tss_version( &credIssuer);
+ i = 1;
+ while( i < argc) {
+ param = argv[ i];
+ if ( strcmp( param, "-if") == 0 || strcmp( param, "--issuer_file") == 0) {
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ filename = argv[i];
+ } else if( strcmp( param, "-dc") == 0 || strcmp( param, "--daa_counter") == 0){
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ daaCounter = atoi(argv[i]);
+ } else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ szTpmPasswd = argv[i];
+ } else {
+ fprintf(stderr, "\n%s:unrecognized option <%s>\n", argv[0], param);
+ return print_usage( argv[0]);
+ }
+ i++;
+ }
+ bi_init( NULL);
+
+ // Create Context
+ LogDebug("Create Context");
+ result = Tspi_Context_Create( &hContext );
+ if ( result != TSS_SUCCESS )
+ {
+ LogError( "Tspi_Context_Create %d\n", result );
+ goto out;
+ }
+ // Connect to Context
+ result = Tspi_Context_Connect( hContext, NULL );
+ if ( result != TSS_SUCCESS) goto out_close;
+ printf("\nConnect to the context: %X\n", hContext);
+
+ if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS)
+ goto out_close;
+ // Get the correct policy using the TPM ownership PASSWD
+ if( (result = Tspi_GetPolicyObject( hTPM,
+ TSS_POLICY_USAGE,
+ &hPolicy)) != TSS_SUCCESS)
+ goto out_close;
+ if( (result = Tspi_Policy_SetSecret( hPolicy,
+ TSS_SECRET_MODE_PLAIN,
+ strlen( szTpmPasswd),
+ szTpmPasswd)) != TSS_SUCCESS)
+ goto out_close;
+ LogDebug("Tspi_Policy_SetSecret hPolicy received;%d\n", hPolicy);
+
+ //Create Object
+ result = obj_daa_add( hContext, &hDAA);
+ if (result != TSS_SUCCESS) {
+ LogError("Tspi_Context_CreateObject:%d\n", result);
+ Tspi_Context_Close(hContext);
+ LogError("%s: %s\n", argv[0], err_string(result));
+ exit(result);
+ }
+ LogDebug("created DAA object:%X", hDAA);
+ issuer = initIssuer( DEFAULT_KEY_CHAIN_LENGTH, filename, argv[0], hContext);
+ if( issuer == NULL) goto out_close;
+
+ // generate receiver attributes and issuer attributes (random)
+ attributesPlatformLength = issuer->pk->capitalRReceiver->length;
+ attributesPlatform = (BYTE **)malloc( attributesPlatformLength * sizeof(BYTE *));
+ bi_new( random);
+ for( i=0; i<(int)attributesPlatformLength; i++) {
+ bi_urandom( random, DAA_PARAM_SIZE_F_I);
+ attributesPlatform[i] = bi_2_nbin( &length, random);
+ if( attributesPlatform[i] == NULL) {
+ LogError("malloc of %d bytes failed", length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto out_close;
+ }
+ }
+ attributesIssuerLength = issuer->pk->capitalRIssuer->length;
+ attributesIssuer = (BYTE **)malloc( attributesIssuerLength * sizeof(BYTE *));
+ for( i=0; i<(int)attributesIssuerLength; i++) {
+ bi_urandom( random, DAA_PARAM_SIZE_F_I);
+ attributesIssuer[i] = bi_2_nbin( &length, random);
+ if( attributesIssuer[i] == NULL) {
+ LogError("malloc of %d bytes failed", length);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto out_close;
+ }
+ }
+ bi_free(random);
+ LogDebug("Generated attributes (Platform=%d,Issuer=%d)",
+ attributesPlatformLength, attributesIssuerLength);
+
+ result = Tspi_TPM_DAA_JoinInit(
+ hDAA, // in
+ hTPM, // in
+ daaCounter, // in
+ (TSS_HKEY)issuer->pk_extern, // in
+ issuer->length_key_chain, // in
+ (TSS_HKEY *)issuer->key_chain, // in
+ issuer->length_key_chain, // in
+ issuer->pk_signatures, // in
+ &capital_UPrimeLength, // out
+ &capitalUPrime, // out
+ &identityProof, // out
+ &joinSession // out
+ );
+ if( result != TSS_SUCCESS) goto out_close;
+
+ result = Tspi_DAA_IssueInit(
+ hDAA, // in
+ (TSS_HKEY)issuer->key_chain[0], // in
+ (TSS_HKEY)issuer->key_pair_extern, // in
+ identityProof, // in
+ capital_UPrimeLength, // in
+ capitalUPrime, // in
+ daaCounter, // in
+ &nonceIssuerLength, // out
+ &nonceIssuer, // out
+ &authenticationChallengeLength, // out
+ &authenticationChallenge, // out
+ &join_issuer_session // out
+ );
+ if( result != TSS_SUCCESS) goto out_close;
+
+ result = Tspi_TPM_DAA_JoinCreateDaaPubKey(
+ hDAA, // in
+ hTPM, // in
+ authenticationChallengeLength, // in
+ authenticationChallenge, // in
+ nonceIssuerLength, // in
+ nonceIssuer, // in
+ attributesPlatformLength, // in
+ attributesPlatform, // in
+ &joinSession, // in & out
+ &credentialRequest // out
+ );
+ if( result != TSS_SUCCESS) goto out_close;
+
+ result = Tspi_DAA_IssueCredential(
+ hDAA, // in
+ attributesIssuerLength, // in
+ attributesIssuer, // in
+ credentialRequest, // in
+ join_issuer_session, // in
+ &credIssuer // out
+ );
+
+ result = Tspi_TPM_DAA_JoinStoreCredential(
+ hDAA, // in
+ hTPM, // in
+ credIssuer, // in
+ joinSession, // in
+ (TSS_HKEY*)&credentialRequest // out
+ );
+ if( result != TSS_SUCCESS) goto out_close;
+
+ printf("Saving credential: %s ", credential_filename);
+ file = fopen( credential_filename, "w");
+ if( save_TSS_DAA_CREDENTIAL( file, &credentialRequest) != 0) {
+ LogError( "[test_join]: Error when saving \'%s\': %s",
+ credential_filename,
+ strerror( errno));
+ result = TSS_E_FAIL;
+ goto out_close;
+ }
+ fclose( file);
+ printf("Done\n");
+
+out_close:
+ Tspi_Context_FreeMemory( hContext, NULL );
+ Tspi_Context_Close( hContext );
+out:
+ bi_release();
+ LogDebug("THE END result=%d:%s",result, err_string( result) );;
+ return result;
+}
diff --git a/src/tspi/daa/daa_structs.c b/src/tspi/daa/daa_structs.c
new file mode 100644
index 0000000..787d5d0
--- /dev/null
+++ b/src/tspi/daa/daa_structs.c
@@ -0,0 +1,1317 @@
+
+/*
+* Licensed Materials - Property of IBM
+*
+* trousers - An open source TCG Software Stack
+*
+* (C) Copyright International Business Machines Corp. 2006
+*
+*/
+
+/*
+This file implements Helper functions for converting / creating and freeing
+internal representation of TSS_DAA structures.
+An external representation is the one define in tss_structs.h.
+An internal representation is using bi_t or bi_ptr for representing big numbers.
+Naming convention: for each structures we can have:
+init_(<STRUCT>, struct *) : initialize the version field
+create_<STRUCT> : init all fields
+free_<STRUCT> : free all fields
+e_2_i_<STRUCT> : convertor from External representation to internal
+i_2_e_<STRUCT> : convertor from Internal to External. This call use a given memory
+allocation function, to allow
+for example to use calloc_tspi, or a "normal" malloc.
+*/
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+#include <strings.h>
+
+#include "daa_parameter.h"
+#include "daa_structs.h"
+#include "tcslog.h"
+
+#define DUMP_DAA_PK_FIELD( field) \
+do { \
+ printf("%s=", #field); \
+ dump_field( pk->field##Length, pk->field); \
+ puts(""); \
+} while(0);
+
+#if 0
+#define STORE_DAA_PK_BI1( field, bi) \
+do { \
+ store_bi( &pk->field##Length, &pk->field, bi); \
+} while(0);
+
+#define STORE_DAA_PK_BI( field, daa_alloc, param_alloc) \
+do { \
+ store_bi( &pk->field##Length,\
+ &pk->field,\
+ pk_internal->field,\
+ daa_alloc,\
+ param_alloc); \
+} while(0);
+
+// used only to read a structure from a file, so only as helping function
+// for TCG application
+static char buffer[1000];
+#endif
+BYTE *convert_alloc( TCS_CONTEXT_HANDLE tcsContext, UINT32 length, BYTE *source) {
+ BYTE *result = calloc_tspi( tcsContext, length);
+
+ if( result == NULL) return NULL;
+ memcpy( result, source, length);
+ free( source);
+ return result;
+}
+
+BYTE *copy_alloc( TCS_CONTEXT_HANDLE tcsContext, UINT32 length, BYTE *source) {
+ BYTE *result = calloc_tspi( tcsContext, length);
+
+ if( result == NULL) return NULL;
+ memcpy( result, source, length);
+ return result;
+}
+
+static void *normal_malloc( size_t size, TSS_HOBJECT object) {
+ void *ret = malloc( size);
+ return ret;
+}
+
+/* store a bi to a buffer and update the length in big endian format */
+void store_bi( UINT32 *length,
+ BYTE **buffer,
+ const bi_ptr i,
+ void * (*daa_alloc)(size_t size, TSS_HOBJECT object),
+ TSS_HOBJECT object
+) {
+ int size;
+
+ *buffer = (BYTE *)daa_alloc( bi_length( i), object);
+ bi_2_nbin1( &size, *buffer, i);
+ *length = size;
+ LogDebug( "[store_bi] host_length:%d network_length:%d[address:%d]\n",
+ size,
+ (int)*length,
+ (int)*buffer);
+}
+
+bi_ptr get_bi( const unsigned long n_length, const BYTE *buffer) {
+ unsigned long length;
+
+ length = n_length;
+ LogDebug( "[get_bi] %d [address:%d -> |%2x|%2x| ]\n",
+ (int)length,
+ (int)buffer,
+ (int)(buffer[0] &0xFF),
+ (int)(buffer[1]&0xFF));
+ return bi_set_as_nbin( length, buffer);
+}
+
+/* length is in network format: big indian */
+void dump_field( int length, BYTE *buffer) {
+ int i;
+
+ for( i=0; i< length; i++) {
+ BYTE byte = (BYTE)(buffer[i] & 0xFF);
+ printf("%02X", byte);
+ }
+}
+
+#if 0
+/* !: do not keep the return buffer */
+char *read_str(FILE *file) {
+ int i;
+ char c;
+
+ fgets( buffer, 1000, file);
+ i=0;
+ while( buffer[i] =='\n' || buffer[i]=='\r' || buffer[i]==' ') i++;
+ do {
+ c = buffer[ i++];
+ } while( c != 0 && c != ' ' && c!='\n' && c!='\r' && c!='#');
+ buffer[ i -1] = 0;
+ return buffer;
+}
+
+/**
+ *
+ * @param file
+ * @return
+ */
+int read_int( FILE *file) {
+ int i, ret;
+ char c;
+
+ fgets( buffer, 1000, file);
+ i=0;
+ while( buffer[i] =='\n' || buffer[i]=='\r' || buffer[i]==' ') i++;
+ do {
+ c = buffer[ i++];
+ } while( c != 0 && c != ' ' && c!='\n' && c!='\r' && c!='#');
+ buffer[ i -1] = 0;
+ sscanf( buffer, "%d", &ret);
+ return ret;
+}
+#endif
+/********************************************************************************************
+* TSS_DAA_SELECTED_ATTRIB
+* this struct is used internally and externally, only a call to
+internal_2_DAA_SELECTED_ATTRIB
+* and DAA_SELECTED_ATTRIB_2_internal will change the struct to be internal or
+external
+********************************************************************************************/
+
+void i_2_e_TSS_DAA_SELECTED_ATTRIB(
+ TSS_DAA_SELECTED_ATTRIB *selected_attrib
+) {
+}
+
+void e_2_i_TSS_DAA_SELECTED_ATTRIB(
+ TSS_DAA_SELECTED_ATTRIB *selected_attrib
+) {
+}
+
+/* work ONLY with internal format
+important: TSS_BOOL is of type int_8_t, so a char, if the size is bigger, we
+will maybe need
+to transform each part to big indian ? or maybe each part is false if equal to
+0, true otherwise.
+*/
+BYTE *to_bytes_TSS_DAA_SELECTED_ATTRIB_internal(
+ int *result_length,
+ TSS_DAA_SELECTED_ATTRIB *selected_attrib
+) {
+ BYTE *result;
+ int index = 0;
+ unsigned int length = selected_attrib->indicesListLength;
+
+ *result_length = sizeof(unsigned int) +
+ (selected_attrib->indicesListLength * sizeof(TSS_BOOL));
+ result = (BYTE *)malloc( *result_length);
+ memcpy( &result[index], &length, sizeof(UINT32));
+ index+=sizeof(UINT32);
+ memcpy( &result[index], selected_attrib->indicesList,
+ sizeof(TSS_BOOL) * selected_attrib->indicesListLength);
+ return result;
+}
+
+/*
+create a TSS_DAA_SELECTED_ATTRIB of length <length> with given selected attributes.
+example of selections of the second and third attributes upon 5:
+create_TSS_DAA_SELECTED_ATTRIB( &selected_attrib, 5, 0, 1, 1, 0, 0);
+*/
+void create_TSS_DAA_SELECTED_ATTRIB( TSS_DAA_SELECTED_ATTRIB *attrib, int length, ...) {
+ va_list ap;
+ int i, select;
+
+ attrib->indicesListLength = length;
+ attrib->indicesList = (TSS_BOOL *)malloc( length * sizeof( TSS_BOOL));
+ va_start (ap, length);
+ for( i=0; i<length; i++) {
+ select = va_arg( ap, int) != 0;
+ attrib->indicesList[i] = select;
+ }
+ va_end (ap);
+}
+
+
+/******************************************************************************************
+* TSS_DAA_SIGN_DATA
+* this struct is used internally and externally, only a call to internal_2_DAA_SIGN_DATA
+* DAA_SIGN_DATA_2_internal will change the struct to be internal or external
+*******************************************************************************************/
+
+void i_2_e_TSS_DAA_SIGN_DATA( TSS_DAA_SIGN_DATA *sign_data) {
+}
+
+void e_2_i_TSS_DAA_SIGN( TSS_DAA_SIGN_DATA *sign_data) {
+}
+
+/********************************************************************************************
+* TSS_DAA_ATTRIB_COMMIT
+********************************************************************************************/
+
+TSS_DAA_ATTRIB_COMMIT_internal *create_TSS_DAA_ATTRIB_COMMIT( bi_ptr beta, bi_ptr sMu) {
+ TSS_DAA_ATTRIB_COMMIT_internal *result =
+ (TSS_DAA_ATTRIB_COMMIT_internal *)malloc( sizeof(TSS_DAA_ATTRIB_COMMIT_internal));
+
+ result->beta = beta;
+ result->sMu = sMu;
+ return result;
+}
+
+
+/********************************************************************************************
+* TSS_DAA_PSEUDONYM_PLAIN
+********************************************************************************************/
+
+TSS_DAA_PSEUDONYM_PLAIN_internal *
+create_TSS_DAA_PSEUDONYM_PLAIN(bi_ptr nV)
+{
+ TSS_DAA_PSEUDONYM_PLAIN_internal *result = (TSS_DAA_PSEUDONYM_PLAIN_internal *)
+ malloc(sizeof(TSS_DAA_PSEUDONYM_PLAIN_internal));
+
+ result->nV = nV;
+ return result;
+}
+
+/********************************************************************************************
+* DAA PRIVATE KEY
+********************************************************************************************/
+/*
+* allocate: ret->p_prime
+* ret->q_prime
+* ret->productPQprime
+*/
+DAA_PRIVATE_KEY_internal *
+create_TSS_DAA_PRIVATE_KEY(bi_ptr pPrime, bi_ptr qPrime)
+{
+ DAA_PRIVATE_KEY_internal *private_key =
+ (DAA_PRIVATE_KEY_internal *)malloc( sizeof( DAA_PRIVATE_KEY_internal));
+
+ private_key->p_prime = bi_new_ptr(); bi_set( private_key->p_prime, pPrime);
+ private_key->q_prime = bi_new_ptr(); bi_set( private_key->q_prime, qPrime);
+ private_key->productPQprime = bi_new_ptr();
+ bi_mul( private_key->productPQprime, pPrime, qPrime);
+ return private_key;
+}
+
+#if 0
+int
+save_DAA_PRIVATE_KEY(FILE *file, const DAA_PRIVATE_KEY_internal *private_key)
+{
+ BI_SAVE( private_key->p_prime , file);
+ BI_SAVE( private_key->q_prime , file);
+ BI_SAVE( private_key->productPQprime, file);
+ return 0;
+}
+
+DAA_PRIVATE_KEY_internal *
+load_DAA_PRIVATE_KEY(FILE *file)
+{
+ DAA_PRIVATE_KEY_internal *private_key =
+ (DAA_PRIVATE_KEY_internal *)malloc( sizeof(DAA_PRIVATE_KEY_internal));
+
+ private_key->p_prime = bi_new_ptr();
+ BI_LOAD( private_key->p_prime, file);
+ private_key->q_prime = bi_new_ptr();
+ BI_LOAD( private_key->q_prime, file);
+ private_key->productPQprime = bi_new_ptr();
+ BI_LOAD( private_key->productPQprime, file);
+ return private_key;
+}
+#endif
+DAA_PRIVATE_KEY_internal *e_2_i_TSS_DAA_PRIVATE_KEY(TSS_DAA_PRIVATE_KEY *private_key) {
+ DAA_PRIVATE_KEY_internal *private_key_internal;
+
+ LogDebug("-> e_2_i_TSS_DAA_PRIVATE_KEY");
+ private_key_internal =
+ (DAA_PRIVATE_KEY_internal *)malloc( sizeof(DAA_PRIVATE_KEY_internal));
+ private_key_internal->p_prime = get_bi( private_key->p_primeLength, private_key->p_prime);
+ private_key_internal->q_prime = get_bi( private_key->q_primeLength, private_key->q_prime);
+ private_key_internal->productPQprime =
+ get_bi( private_key->productPQprimeLength, private_key->productPQprime);
+ LogDebug("<- e_2_i_TSS_DAA_PRIVATE_KEY");
+ return private_key_internal;
+}
+
+TSS_DAA_PRIVATE_KEY *
+i_2_e_TSS_DAA_PRIVATE_KEY(DAA_PRIVATE_KEY_internal *private_key_internal,
+ void * (*daa_alloc)(size_t size, TSS_HOBJECT object),
+ TSS_HOBJECT param_alloc)
+{
+ TSS_DAA_PRIVATE_KEY *result;
+
+ LogDebug("-> i_2_e_TSS_DAA_PRIVATE_KEY");
+ result = (TSS_DAA_PRIVATE_KEY *)daa_alloc( sizeof(TSS_DAA_PRIVATE_KEY), param_alloc);
+ init_tss_version( result);
+ store_bi( &(result->p_primeLength),
+ &(result->p_prime),
+ private_key_internal->p_prime,
+ daa_alloc,
+ param_alloc);
+ store_bi( &(result->q_primeLength),
+ &(result->q_prime),
+ private_key_internal->q_prime,
+ daa_alloc,
+ param_alloc);
+ store_bi( &(result->productPQprimeLength),
+ &(result->productPQprime),
+ private_key_internal->productPQprime,
+ daa_alloc,
+ param_alloc);
+ LogDebug("<- i_2_e_TSS_DAA_PRIVATE_KEY");
+ return result;
+}
+
+/********************************************************************************************
+* KEY PAIR WITH PROOF
+********************************************************************************************/
+
+#if 0
+
+/* moved to daa_debug.c */
+
+int
+save_KEY_PAIR_WITH_PROOF(FILE *file,
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof)
+{
+ save_DAA_PK_internal( file, key_pair_with_proof->pk);
+ save_DAA_PRIVATE_KEY( file, key_pair_with_proof->private_key);
+ save_DAA_PK_PROOF_internal( file, key_pair_with_proof->proof);
+
+ return 0;
+}
+
+KEY_PAIR_WITH_PROOF_internal *
+load_KEY_PAIR_WITH_PROOF(FILE *file)
+{
+ KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof =
+ (KEY_PAIR_WITH_PROOF_internal *)malloc(sizeof(KEY_PAIR_WITH_PROOF_internal));
+
+ key_pair_with_proof->pk = load_DAA_PK_internal(file);
+ key_pair_with_proof->private_key = load_DAA_PRIVATE_KEY(file);
+ key_pair_with_proof->proof = load_DAA_PK_PROOF_internal(file);
+
+ return key_pair_with_proof;
+}
+
+#endif
+/* allocated using instrumented daa_alloc */
+TSS_DAA_KEY_PAIR *get_TSS_DAA_KEY_PAIR(KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof,
+ void * (*daa_alloc)(size_t size, TSS_HOBJECT object),
+ TSS_HOBJECT param_alloc)
+{
+ TSS_DAA_KEY_PAIR *result;
+
+ LogDebug("-> i_2_e_KEY_PAIR_WITH_PROOF");
+
+ result = (TSS_DAA_KEY_PAIR *)daa_alloc(sizeof(TSS_DAA_KEY_PAIR), param_alloc);
+ init_tss_version(result);
+ result->private_key = i_2_e_TSS_DAA_PRIVATE_KEY(key_pair_with_proof->private_key,
+ daa_alloc, param_alloc);
+ result->public_key = i_2_e_TSS_DAA_PK( key_pair_with_proof->pk, daa_alloc, param_alloc);
+
+ LogDebug("<- i_2_e_KEY_PAIR_WITH_PROOF");
+
+ return result;
+}
+
+
+/********************************************************************************************
+* TSS_DAA_PK
+********************************************************************************************/
+
+/* pk_internal->capitalY must be alocated using ALLOC_BI_ARRAY() */
+void
+populate_capitalY(TSS_DAA_PK_internal *pk_internal)
+{
+ int i;
+
+ bi_new_array(pk_internal->capitalY,
+ pk_internal->capitalRReceiver->length + pk_internal->capitalRIssuer->length);
+
+ // CAPITAL Y ( capitalRReceiver )
+ for (i = 0; i < pk_internal->capitalRReceiver->length; i++)
+ pk_internal->capitalY->array[i] = pk_internal->capitalRReceiver->array[i];
+ // CAPITAL Y ( capitalRIssuer)
+ for (i = 0; i < pk_internal->capitalRIssuer->length; i++)
+ pk_internal->capitalY->array[pk_internal->capitalRReceiver->length+i] =
+ pk_internal->capitalRIssuer->array[i];
+}
+
+void
+compute_capitalSprime(TSS_DAA_PK_internal *pk_internal)
+{
+ bi_t bi_tmp;
+
+ bi_new(bi_tmp);
+ pk_internal->capitalSprime = bi_new_ptr();
+ bi_shift_left( bi_tmp, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT);
+ bi_mod_exp(pk_internal->capitalSprime, pk_internal->capitalS, bi_tmp, pk_internal->modulus);
+ bi_free( bi_tmp);
+}
+
+/*
+* create anf feel a TSS_DAA_PK_internal structures
+* ! this function keep pointer on all parameters
+*/
+TSS_DAA_PK_internal *
+create_DAA_PK(const bi_ptr modulus,
+ const bi_ptr capitalS,
+ const bi_ptr capitalZ,
+ const bi_ptr capitalR0,
+ const bi_ptr capitalR1,
+ const bi_ptr gamma,
+ const bi_ptr capitalGamma,
+ const bi_ptr rho,
+ const bi_array_ptr capitalRReceiver,
+ const bi_array_ptr capitalRIssuer,
+ const int issuerBaseNameLength,
+ BYTE * const issuerBaseName)
+{
+ TSS_DAA_PK_internal *pk_internal;
+
+ LogDebug("-> create_DAA_PK");
+ pk_internal = (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal));
+ pk_internal->modulus = modulus;
+ pk_internal->capitalS = capitalS;
+ pk_internal->capitalZ = capitalZ;
+ pk_internal->capitalR0 = capitalR0;
+ pk_internal->capitalR1 = capitalR1;
+ pk_internal->gamma = gamma;
+ pk_internal->capitalGamma = capitalGamma;
+ pk_internal->rho = rho;
+ pk_internal->capitalRReceiver = capitalRReceiver;
+ pk_internal->capitalRIssuer = capitalRIssuer;
+ pk_internal->capitalY = ALLOC_BI_ARRAY();
+ populate_capitalY( pk_internal);
+ pk_internal->issuerBaseNameLength = issuerBaseNameLength;
+ pk_internal->issuerBaseName = issuerBaseName;
+ compute_capitalSprime( pk_internal);
+
+ LogDebug("<- create_DAA_PK");
+
+ return pk_internal;
+}
+
+#if 0
+
+/* moved to daa_debug.c */
+
+int
+save_DAA_PK_internal(FILE *file, const TSS_DAA_PK_internal *pk_internal)
+{
+ char *buffer;
+
+ LogDebug("-> save_DAA_PK_internal");
+
+ BI_SAVE( pk_internal->modulus, file);
+ BI_SAVE( pk_internal->capitalS, file);
+ BI_SAVE( pk_internal->capitalZ, file);
+ BI_SAVE( pk_internal->capitalR0, file);
+ BI_SAVE( pk_internal->capitalR1, file);
+ BI_SAVE( pk_internal->gamma, file);
+ BI_SAVE( pk_internal->capitalGamma, file);
+ BI_SAVE( pk_internal->rho, file);
+ BI_SAVE_ARRAY( pk_internal->capitalRReceiver, file);
+ BI_SAVE_ARRAY( pk_internal->capitalRIssuer, file);
+ fprintf( file, "%d\n", pk_internal->issuerBaseNameLength);
+ buffer = (char *)malloc( pk_internal->issuerBaseNameLength + 1);
+ memcpy( buffer, pk_internal->issuerBaseName, pk_internal->issuerBaseNameLength);
+ buffer[ pk_internal->issuerBaseNameLength] = 0;
+ fprintf( file, "%s\n", buffer);
+ free( buffer);
+
+ LogDebug("<- save_DAA_PK_internal");
+
+ return 0;
+}
+
+TSS_DAA_PK_internal *
+load_DAA_PK_internal(FILE *file)
+{
+ TSS_DAA_PK_internal *pk_internal =
+ (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal));
+ char *read_buffer;
+
+ pk_internal->modulus = bi_new_ptr();
+ BI_LOAD( pk_internal->modulus, file);
+ pk_internal->capitalS = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalS, file);
+ pk_internal->capitalZ = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalZ, file);
+ pk_internal->capitalR0 = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalR0, file);
+ pk_internal->capitalR1 = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalR1, file);
+ pk_internal->gamma = bi_new_ptr();
+ BI_LOAD( pk_internal->gamma, file);
+ pk_internal->capitalGamma = bi_new_ptr();
+ BI_LOAD( pk_internal->capitalGamma, file);
+ pk_internal->rho = bi_new_ptr();
+ BI_LOAD( pk_internal->rho, file);
+ pk_internal->capitalRReceiver = ALLOC_BI_ARRAY();
+ BI_LOAD_ARRAY( pk_internal->capitalRReceiver, file);
+ pk_internal->capitalRIssuer = ALLOC_BI_ARRAY();
+ BI_LOAD_ARRAY( pk_internal->capitalRIssuer, file);
+ pk_internal->capitalY = ALLOC_BI_ARRAY();
+ populate_capitalY( pk_internal);
+ pk_internal->issuerBaseNameLength = read_int( file);
+ read_buffer = read_str( file);
+ pk_internal->issuerBaseName = malloc( pk_internal->issuerBaseNameLength);
+ memcpy( pk_internal->issuerBaseName, read_buffer, pk_internal->issuerBaseNameLength);
+ compute_capitalSprime( pk_internal);
+ return pk_internal;
+}
+
+#endif
+void
+dump_DAA_PK_internal(char *name, TSS_DAA_PK_internal *pk_internal)
+{
+ LogDebug("Dump TSS_DAA_PK_internal:%s\n", name);
+
+ DUMP_BI( pk_internal->modulus);
+ DUMP_BI( pk_internal->capitalS);
+ DUMP_BI( pk_internal->capitalZ);
+ DUMP_BI( pk_internal->capitalR0);
+ DUMP_BI( pk_internal->capitalR1);
+ DUMP_BI( pk_internal->gamma);
+ DUMP_BI( pk_internal->capitalGamma);
+ DUMP_BI( pk_internal->rho);
+ DUMP_BI_ARRAY( pk_internal->capitalRReceiver);
+ DUMP_BI_ARRAY( pk_internal->capitalRIssuer);
+
+ LogDebug("issuerBaseName = %s\n", pk_internal->issuerBaseName);
+ LogDebug("End Dump TSS_DAA_PK_internal:%s\n", name);
+}
+
+/*
+* Encode the DAA_PK like java.security.Key#getEncoded
+*/
+BYTE *
+encoded_DAA_PK_internal(int *result_length, const TSS_DAA_PK_internal *pk)
+{
+ int length_issuer_base_name = pk->issuerBaseNameLength;
+ int total_length = DAA_PARAM_TSS_VERSION_LENGTH +
+ 5 * ((DAA_PARAM_SIZE_RSA_MODULUS / 8)+ sizeof(int)) +
+ 2 * ((DAA_PARAM_SIZE_MODULUS_GAMMA / 8)+sizeof(int)) +
+ 1 * ((DAA_PARAM_SIZE_RHO / 8)+sizeof(int)) +
+ pk->capitalY->length*(((DAA_PARAM_SIZE_RSA_MODULUS / 8)+sizeof(int)))
+ + length_issuer_base_name;
+ BYTE *result = (BYTE *)malloc(total_length);
+ int i, index = 0, length, big_indian_length;
+
+ if (result == NULL)
+ return NULL;
+
+ LogDebug("total_length=%d", total_length);
+ for (index = 0; index < DAA_PARAM_TSS_VERSION_LENGTH; index++)
+ result[index] = DAA_PARAM_TSS_VERSION[index];
+ // n, capitalS, capitalZ, capitalR0, capitalR1
+ length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
+ big_indian_length = length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->modulus);
+ index += length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->capitalS);
+ index += length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->capitalZ);
+ index += length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->capitalR0);
+ index += length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->capitalR1);
+ index += length;
+ // gamma, capitalGamma
+ length = DAA_PARAM_SIZE_MODULUS_GAMMA / 8;
+ big_indian_length = length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->gamma);
+ index += length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->capitalGamma);
+ index += length;
+ // rho
+ length = DAA_PARAM_SIZE_RHO / 8;
+ big_indian_length = length;
+ memcpy(&result[index], &big_indian_length, sizeof(int));
+ index += sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->rho);
+ index += length;
+ // capitalY
+ length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
+ big_indian_length = length;
+
+ for( i=0; i<pk->capitalY->length; i++) {
+ memcpy( &result[index], &big_indian_length, sizeof(int));
+ index+=sizeof(int);
+ bi_2_byte_array( &result[index], length, pk->capitalY->array[i]);
+ index+=length;
+ }
+ // basename
+ memcpy( &result[index], pk->issuerBaseName, length_issuer_base_name);
+ index+=length_issuer_base_name;
+ *result_length = index;
+
+ LogDebug("return length=%d", index);
+
+ return result;
+}
+
+/* create anf feel a TSS_DAA_PK structures */
+TSS_DAA_PK *
+i_2_e_TSS_DAA_PK(TSS_DAA_PK_internal *pk_internal,
+ void *(*daa_alloc)(size_t size, TSS_HOBJECT param_alloc),
+ TSS_HOBJECT param_alloc)
+{
+ int i;
+ int capitalYLength;
+ int capitalYLength2;
+ TSS_DAA_PK *pk;
+
+ LogDebug("-> i_2_e_TSS_DAA_PK");
+ pk = (TSS_DAA_PK *)daa_alloc( sizeof(TSS_DAA_PK), param_alloc);
+ init_tss_version( pk);
+ if (pk == NULL) {
+ LogError("Can not allocate the TSS_DAA_PK structure");
+ return NULL;
+ }
+ STORE_DAA_PK_BI( modulus, daa_alloc, param_alloc);
+ STORE_DAA_PK_BI( capitalS, daa_alloc, param_alloc);
+ STORE_DAA_PK_BI( capitalZ, daa_alloc, param_alloc);
+ STORE_DAA_PK_BI( capitalR0, daa_alloc, param_alloc);
+ STORE_DAA_PK_BI( capitalR1, daa_alloc, param_alloc);
+ STORE_DAA_PK_BI( gamma, daa_alloc, param_alloc);
+ STORE_DAA_PK_BI( capitalGamma, daa_alloc, param_alloc);
+ STORE_DAA_PK_BI( rho, daa_alloc, param_alloc);
+ capitalYLength = pk_internal->capitalY->length;
+ capitalYLength2 = bi_nbin_size( pk_internal->capitalY->array[0]);
+ LogDebug("[capitalYLength=%d capitalYLength2=%d total size=%d]\n",
+ capitalYLength, capitalYLength2, sizeof(BYTE) * capitalYLength *
+ capitalYLength2);
+ pk->capitalY = (BYTE **) daa_alloc( sizeof(BYTE *) * capitalYLength, param_alloc );
+ for (i = 0; i < capitalYLength; i++) {
+ if( bi_nbin_size( pk_internal->capitalY->array[i]) != capitalYLength2) {
+ // LOG ERROR
+ LogError("Error during feel operation of capitalY (index=%d capitalYLength"
+ "2=%d, currentSize=%d)\n", i, capitalYLength2,
+ (int)bi_nbin_size(pk_internal->capitalY->array[i]));
+ }
+ BYTE *buffer = (BYTE*) daa_alloc( sizeof(BYTE) * capitalYLength2, param_alloc);
+ bi_2_byte_array( buffer, capitalYLength2, pk_internal->capitalY->array[i]);
+ // bi_2_nbin1( &checkSize, buffer, pk_internal->capitalY->array[i]);
+ pk->capitalY[i] = buffer;
+ LogDebug( "[i=%d currentsize=%d buffer[%d]=[%2x|%2x]\n",
+ i,
+ (int)bi_nbin_size( pk_internal->capitalY->array[i]),
+ (int)pk->capitalY[i],
+ (int)pk->capitalY[i][0],
+ (int)pk->capitalY[i][1]);
+ }
+ pk->capitalYLength = capitalYLength;
+ pk->capitalYLength2 = capitalYLength2;
+ pk->capitalYPlatformLength = pk_internal->capitalRReceiver->length;
+ LogDebug("issuer= len=%d", pk_internal->issuerBaseNameLength);
+ pk->issuerBaseNameLength = pk_internal->issuerBaseNameLength;
+ pk->issuerBaseName = (BYTE *)daa_alloc(pk_internal->issuerBaseNameLength, param_alloc);
+ memcpy( pk->issuerBaseName,
+ pk_internal->issuerBaseName,
+ pk_internal->issuerBaseNameLength);
+ LogDebug("i_2_e_TSS_DAA_PK extern_issuer=%s intern_issuer=%s\n",
+ pk->issuerBaseName,
+ pk_internal->issuerBaseName);
+ LogDebug("<- i_2_e_TSS_DAA_PK");
+ return pk;
+}
+
+/**/
+TSS_DAA_PK_internal *
+e_2_i_TSS_DAA_PK( TSS_DAA_PK *pk)
+{
+ TSS_DAA_PK_internal *pk_internal =
+ (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal));
+ unsigned long capitalYLength, capitalYLength2, capitalYPlatformLength;
+ UINT32 i;
+ int issuer_length;
+
+ // pk_internal->modulus = GET_DAA_PK_BI( modulus);
+ pk_internal->modulus = get_bi(pk->modulusLength, pk->modulus);
+ pk_internal->capitalS = get_bi(pk->capitalSLength, pk->capitalS);
+ pk_internal->capitalZ = get_bi(pk->capitalZLength, pk->capitalZ);
+ pk_internal->capitalR0 = get_bi(pk->capitalR0Length, pk->capitalR0);
+ pk_internal->capitalR1 = get_bi(pk->capitalR1Length, pk->capitalR1);
+ pk_internal->gamma = get_bi(pk->gammaLength, pk->gamma);
+ pk_internal->capitalGamma = get_bi(pk->capitalGammaLength, pk->capitalGamma);
+ pk_internal->rho = get_bi(pk->rhoLength, pk->rho);
+ capitalYLength = pk->capitalYLength;
+ capitalYLength2= pk->capitalYLength2;
+ capitalYPlatformLength = pk->capitalYPlatformLength;
+ LogDebug( "capitalYLength:%ld capitalYLength2:%ld capitalYPlatformLength:%ld\n",
+ capitalYLength, capitalYLength2, capitalYPlatformLength);
+
+ pk_internal->capitalRReceiver = ALLOC_BI_ARRAY();
+ bi_new_array2(pk_internal->capitalRReceiver, capitalYPlatformLength);
+ for (i = 0; i < capitalYPlatformLength; i++) {
+ LogDebug( "i=%d\n", i);
+ pk_internal->capitalRReceiver->array[i] =
+ get_bi(pk->capitalYLength2, pk->capitalY[i]);
+ }
+ pk_internal->capitalRIssuer = ALLOC_BI_ARRAY();
+ bi_new_array2( pk_internal->capitalRIssuer, capitalYLength -
+ capitalYPlatformLength);
+ for( ; i<capitalYLength; i++) {
+ pk_internal->capitalRIssuer->array[ i - capitalYPlatformLength] =
+ get_bi( pk->capitalYLength2, pk->capitalY[i]);
+ }
+ pk_internal->capitalY = ALLOC_BI_ARRAY();
+ populate_capitalY( pk_internal);
+ issuer_length = pk->issuerBaseNameLength;
+ pk_internal->issuerBaseNameLength = issuer_length;
+ LogDebug( "issuer_length=%d\n", issuer_length);
+ pk_internal->issuerBaseName = (BYTE *)malloc( issuer_length);
+ memcpy( pk_internal->issuerBaseName, pk->issuerBaseName, issuer_length);
+ LogDebug("e_2_i_TSS_DAA_PK extern_issuer=%s intern_issuer=%s\n",
+ pk->issuerBaseName,
+ pk_internal->issuerBaseName);
+ compute_capitalSprime( pk_internal); // allocation
+ return pk_internal;
+}
+
+void
+free_TSS_DAA_PK_internal(TSS_DAA_PK_internal *pk_internal)
+{
+ bi_free_ptr( pk_internal->capitalSprime);
+ free( pk_internal->issuerBaseName);
+ free( pk_internal->capitalY);
+ bi_free_array( pk_internal->capitalRIssuer);
+ bi_free_array( pk_internal->capitalRReceiver);
+ bi_free_ptr( pk_internal->rho);
+ bi_free_ptr( pk_internal->capitalGamma);
+ bi_free_ptr( pk_internal->gamma);
+ bi_free_ptr( pk_internal->capitalR1);
+ bi_free_ptr( pk_internal->capitalR0);
+ bi_free_ptr( pk_internal->capitalZ);
+ bi_free_ptr( pk_internal->capitalS);
+ bi_free_ptr( pk_internal->modulus);
+ free( pk_internal);
+}
+
+/* free a TSS_DAA_PK structures */
+void
+free_TSS_DAA_PK(TSS_DAA_PK *pk)
+{
+ int i;
+
+ LogDebug("-> free_TSS_DAA_PK");
+ free( pk->modulus);
+ free( pk->capitalS);
+ free( pk->capitalZ);
+ free( pk->capitalR0);
+ free( pk->capitalR1);
+ free( pk->gamma);
+ free( pk->capitalGamma);
+ free( pk->rho);
+ for( i=0; i<(int)pk->capitalYLength; i++) {
+ free( pk->capitalY[i]);
+ }
+ free( pk->capitalY);
+ free( pk->issuerBaseName);
+ free( pk);
+ LogDebug("<- free_TSS_DAA_PK");
+
+}
+
+TPM_DAA_ISSUER *
+convert2issuer_settings(TSS_DAA_PK_internal *pk_internal)
+{
+ TPM_DAA_ISSUER *result = (TPM_DAA_ISSUER *)malloc(sizeof(TPM_DAA_ISSUER));
+ EVP_MD_CTX mdctx;
+ UINT32 length;
+ BYTE *array = (BYTE*)malloc((DAA_PARAM_SIZE_RSA_MODULUS+7)/8);
+
+ LogDebug("convert2issuer_settings");
+ EVP_MD_CTX_init(&mdctx);
+ // TAG
+ result->tag = htons( TPM_TAG_DAA_ISSUER);
+ // capitalR0
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ bi_2_byte_array( array,
+ length = (bi_length( pk_internal->capitalR0)+7)/8,
+ pk_internal->capitalR0);
+ LogDebug("capitalR0 length=%d", length);
+ EVP_DigestUpdate(&mdctx, array, length);
+ EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_R0), NULL);
+ // capitalR1
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ bi_2_byte_array( array,
+ length = (bi_length( pk_internal->capitalR1)+7)/8,
+ pk_internal->capitalR1);
+ LogDebug("capitalR1 length=%d", length);
+ EVP_DigestUpdate(&mdctx, array, length);
+ EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_R1), NULL);
+ // capitalS (S0)
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ bi_2_byte_array( array,
+ length = (bi_length( pk_internal->capitalS)+7)/8,
+ pk_internal->capitalS);
+ LogDebug("capitalS length=%d", length);
+ EVP_DigestUpdate(&mdctx, array, length);
+ EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_S0), NULL);
+ // capitalSprime (S1)
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ bi_2_byte_array( array,
+ length = (bi_length( pk_internal->capitalSprime)+7)/8,
+ pk_internal->capitalSprime);
+ LogDebug("capitalSprime length=%d", length);
+ EVP_DigestUpdate(&mdctx, array, length);
+ EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_S1), NULL);
+ // modulus (n)
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ bi_2_byte_array( array,
+ length = (bi_length( pk_internal->modulus)+7)/8,
+ pk_internal->modulus);
+ LogDebug("modulus length=%d", length);
+ EVP_DigestUpdate(&mdctx, array, length);
+ EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_n), NULL);
+ // modulus (n)
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ bi_2_byte_array( array,
+ length = (bi_length( pk_internal->capitalGamma)+7)/8,
+ pk_internal->capitalGamma);
+ LogDebug("capitalGamma length=%d", length);
+ EVP_DigestUpdate(&mdctx, array, length);
+ free(array);
+ EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_gamma), NULL);
+ EVP_MD_CTX_cleanup(&mdctx);
+ // rho
+ bi_2_byte_array( (BYTE *)&(result->DAA_generic_q), 26, pk_internal->rho);
+ return result;
+}
+
+BYTE *
+issuer_2_byte_array(TPM_DAA_ISSUER *tpm_daa_issuer, int *length)
+{
+ UINT32 size = sizeof(UINT16) + ( 6 * TPM_SHA1_160_HASH_LEN) + 26;
+ BYTE * result = (BYTE *)malloc( sizeof(BYTE)*size);
+ UINT32 i = 0;
+
+ memcpy( &result[i], &(tpm_daa_issuer->tag), sizeof(UINT16));
+ i+=sizeof(UINT16);
+ memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_R0), TPM_SHA1_160_HASH_LEN);
+ i+=TPM_SHA1_160_HASH_LEN;
+ memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_R1), TPM_SHA1_160_HASH_LEN);
+ i+=TPM_SHA1_160_HASH_LEN;
+ memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_S0), TPM_SHA1_160_HASH_LEN);
+ i+=TPM_SHA1_160_HASH_LEN;
+ memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_S1), TPM_SHA1_160_HASH_LEN);
+ i+=TPM_SHA1_160_HASH_LEN;
+ memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_n), TPM_SHA1_160_HASH_LEN);
+ i+=TPM_SHA1_160_HASH_LEN;
+ memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_gamma), TPM_SHA1_160_HASH_LEN);
+ i+=TPM_SHA1_160_HASH_LEN;
+ memcpy( &result[i], &(tpm_daa_issuer->DAA_generic_q), 26);
+ *length = size;
+ return result;
+}
+
+/********************************************************************************************
+* TSS_DAA_PK_PROOF
+********************************************************************************************/
+
+/*
+* this function keep references on:
+* - challenge (BYTE *)
+* - response (bi_array_ptr *)
+*/
+TSS_DAA_PK_PROOF_internal *
+create_DAA_PK_PROOF(BYTE* const challenge,
+ const int length_challenge,
+ bi_array_ptr *response,
+ const int length_response)
+{
+ TSS_DAA_PK_PROOF_internal *pk_proof;
+
+#ifdef DAA_DEBUG
+ printf("create_DAA_PK_PROOF_internal\n");
+#endif
+ pk_proof = (TSS_DAA_PK_PROOF_internal *)malloc( sizeof(TSS_DAA_PK_PROOF_internal));
+ pk_proof->challenge = challenge;
+ pk_proof->length_challenge = length_challenge;
+ pk_proof->response = response;
+ pk_proof->length_response = length_response;
+ return pk_proof;
+}
+
+#if 0
+int
+save_DAA_PK_PROOF_internal(FILE *file, TSS_DAA_PK_PROOF_internal *proof)
+{
+ int i;
+
+#ifdef DAA_DEBUG
+ printf("save_DAA_PK_PROOF_internal");
+#endif
+ fprintf(file, "%d # %s.length\n", proof->length_challenge, "challenge");
+ fprintf(file, "%s\n", dump_byte_array( proof->length_challenge,
+ proof->challenge));
+ fprintf(file, "%d # %s.length\n", proof->length_response, "response");
+ for (i = 0; i < proof->length_response; i++) {
+ BI_SAVE_ARRAY( proof->response[i], file);
+ }
+
+ return 0;
+}
+
+/* load <proof> using <filename> */
+/* allocation of: */
+/* proof->challenge (BYTE*) */
+/* response (bi_array_ptr) */
+TSS_DAA_PK_PROOF_internal *
+load_DAA_PK_PROOF_internal(FILE *file)
+{
+ TSS_DAA_PK_PROOF_internal *proof =
+ (TSS_DAA_PK_PROOF_internal *)malloc(sizeof(TSS_DAA_PK_PROOF_internal));
+ char *read_buffer;
+ int i;
+
+#ifdef DAA_DEBUG
+ printf("load_DAA_PK_PROOF_internal");
+#endif
+ proof->length_challenge = read_int( file);
+ read_buffer = read_str( file);
+ proof->challenge = retrieve_byte_array( &(proof->length_challenge),read_buffer);
+ proof->length_response = read_int( file);
+ proof->response = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * proof->length_response);
+ for (i = 0; i < proof->length_response; i++) {
+ proof->response[i] = ALLOC_BI_ARRAY();
+ BI_LOAD_ARRAY( proof->response[i], file);
+ }
+ return proof;
+}
+#endif
+
+TSS_DAA_PK_PROOF *
+i_2_e_TSS_DAA_PK_PROOF(TSS_DAA_PK_PROOF_internal*pk_internal_proof,
+ void * (*daa_alloc)(size_t size, TSS_HOBJECT param),
+ TSS_HOBJECT param_alloc)
+{
+ TSS_DAA_PK_PROOF *pk_proof =
+ (TSS_DAA_PK_PROOF *)daa_alloc( sizeof(TSS_DAA_PK_PROOF), param_alloc);
+ int i, j;
+ int length_response2;
+ int length_response3;
+
+ init_tss_version( pk_proof);
+ // CHALLENGE
+ pk_proof->challengeLength = pk_internal_proof->length_challenge;
+ pk_proof->challenge = (BYTE *)daa_alloc( pk_internal_proof->length_challenge,
+ param_alloc);
+ memcpy( pk_proof->challenge, pk_internal_proof->challenge,
+ pk_internal_proof->length_challenge);
+ // RESPONSES
+ pk_proof->responseLength = pk_internal_proof->length_response;
+ length_response2 = pk_internal_proof->response[0]->length;
+ pk_proof->responseLength2 = length_response2;
+ length_response3 = bi_nbin_size(
+ pk_internal_proof->response[0]->array[0]);
+ if( length_response3 & 1) length_response3++; // length_response3 should be paire
+ pk_proof->responseLength3 = length_response3;
+ pk_proof->response = (BYTE ***)daa_alloc( sizeof(BYTE **) *
+ pk_internal_proof->length_response, param_alloc);
+ for(i = 0; i < pk_internal_proof->length_response; i++) {
+ pk_proof->response[i] = (BYTE **)daa_alloc( sizeof(BYTE *) * length_response2,
+ param_alloc);
+ for( j = 0; j < length_response2; j++) {
+ (pk_proof->response[i])[j] = (BYTE *)malloc(
+ sizeof(BYTE) * length_response3);
+ bi_2_byte_array( pk_proof->response[i][j],
+ length_response3,
+ pk_internal_proof->response[i]->array[j]);
+ }
+ }
+ return pk_proof;
+}
+
+TSS_DAA_PK_PROOF_internal *
+e_2_i_TSS_DAA_PK_PROOF(TSS_DAA_PK_PROOF *pk_proof)
+{
+ int i, j, response_length2;
+ TSS_DAA_PK_PROOF_internal *pk_proof_internal =
+ (TSS_DAA_PK_PROOF_internal *)malloc( sizeof( TSS_DAA_PK_PROOF_internal));
+
+ // CHALLENGE
+ pk_proof_internal->length_challenge = pk_proof->challengeLength;
+#ifdef DAA_DEBUG
+ fprintf(stderr, "issuer_length=%d\n", pk_proof_internal->length_challenge);
+#endif
+ pk_proof_internal->challenge = (BYTE *)malloc( pk_proof_internal->length_challenge);
+ memcpy( pk_proof_internal->challenge,
+ pk_proof->challenge,
+ pk_proof_internal->length_challenge);
+ // RESPONSES
+ pk_proof_internal->length_response = pk_proof->responseLength;
+ response_length2 = pk_proof->responseLength2;
+ pk_proof_internal->response =
+ (bi_array_ptr *)malloc( sizeof(bi_array_ptr) *
+ pk_proof_internal->length_response);
+ for(i = 0; i<pk_proof_internal->length_response; i++) {
+ pk_proof_internal->response[i] = ALLOC_BI_ARRAY();
+ bi_new_array2( pk_proof_internal->response[i], response_length2);
+ for( j = 0; j < response_length2; j++) {
+ pk_proof_internal->response[i]->array[j] =
+ get_bi( pk_proof->responseLength3, pk_proof->response[i][j]);
+ }
+ }
+ return pk_proof_internal;
+}
+
+
+/********************************************************************************************
+* TSS_DAA_JOIN_ISSUER_SESSION
+********************************************************************************************/
+
+TSS_DAA_JOIN_ISSUER_SESSION_internal *
+create(TSS_DAA_PK_PROOF_internal *issuerKeyPair,
+ TPM_DAA_ISSUER *issuerAuthKey,
+ TSS_DAA_IDENTITY_PROOF *identityProof,
+ bi_ptr capitalUprime,
+ int daaCounter,
+ int nonceIssuerLength,
+ BYTE *nonceIssuer,
+ int nonceEncryptedLength,
+ BYTE *nonceEncrypted)
+{
+ TSS_DAA_JOIN_ISSUER_SESSION_internal *result =
+ (TSS_DAA_JOIN_ISSUER_SESSION_internal *)malloc(
+ sizeof(TSS_DAA_JOIN_ISSUER_SESSION_internal));
+
+ result->issuerAuthKey = issuerAuthKey;
+ result->issuerKeyPair = issuerKeyPair;
+ result->identityProof = identityProof;
+ result->capitalUprime = capitalUprime;
+ result->daaCounter = daaCounter;
+ result->nonceIssuerLength = nonceIssuerLength;
+ result->nonceIssuer = nonceIssuer;
+ result->nonceEncryptedLength = nonceEncryptedLength;
+ result->nonceEncrypted = nonceEncrypted;
+ return result;
+}
+
+
+/********************************************************************************************
+ * TSS_DAA_SIGNATURE
+ ********************************************************************************************/
+
+TSS_DAA_SIGNATURE_internal*
+e_2_i_TSS_DAA_SIGNATURE(TSS_DAA_SIGNATURE* signature)
+{
+ TSS_DAA_SIGNATURE_internal *signature_intern =
+ (TSS_DAA_SIGNATURE_internal *)malloc( sizeof( TSS_DAA_SIGNATURE_internal));
+ int i, length;
+
+ signature_intern->zeta = bi_set_as_nbin( signature->zetaLength, signature->zeta);
+ signature_intern->capitalT = bi_set_as_nbin( signature->capitalTLength,
+ signature->capitalT);
+ signature_intern->challenge_length = signature->challengeLength;
+ signature_intern->challenge = (BYTE *)malloc( signature->challengeLength);
+ memcpy( signature_intern->challenge,
+ signature->challenge,
+ signature->challengeLength);
+ signature_intern->nonce_tpm_length = signature->nonceTpmLength;
+ signature_intern->nonce_tpm = (BYTE *)malloc( signature->nonceTpmLength);
+ memcpy( signature_intern->nonce_tpm, signature->nonceTpm, signature->nonceTpmLength);
+ signature_intern->sV = bi_set_as_nbin( signature->sVLength, signature->sV);
+ signature_intern->sF0 = bi_set_as_nbin( signature->sF0Length, signature->sF0);
+ signature_intern->sF1 = bi_set_as_nbin( signature->sF1Length, signature->sF1);
+ signature_intern->sE = bi_set_as_nbin( signature->sELength, signature->sE);
+ signature_intern->sA = (bi_array_ptr)malloc( sizeof( bi_array));
+ bi_new_array2( signature_intern->sA, signature->sALength);
+ length = ( DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8;
+ for (i = 0; i < (int)signature->sALength; i++) {
+ signature_intern->sA->array[i] = bi_set_as_nbin( length, signature->sA[i]);
+ }
+
+ return signature_intern;
+}
+
+void
+free_TSS_DAA_SIGNATURE_internal(TSS_DAA_SIGNATURE_internal *signature)
+{
+ bi_free_array( signature->sA);
+ bi_free_ptr( signature->sE);
+ bi_free_ptr( signature->sF1);
+ bi_free_ptr( signature->sF0);
+ bi_free_ptr( signature->sV);
+ free( signature->nonce_tpm);
+ free( signature->challenge);
+ bi_free_ptr( signature->capitalT);
+ bi_free_ptr( signature->zeta);
+ free( signature);
+}
+
+#if 0
+/********************************************************************************************
+ TSS_DAA_CRED_ISSUER
+********************************************************************************************/
+
+TSS_DAA_CRED_ISSUER *
+load_TSS_DAA_CRED_ISSUER(FILE *file)
+{
+ TSS_DAA_CRED_ISSUER *credential =
+ (TSS_DAA_CRED_ISSUER *)malloc(sizeof(TSS_DAA_CRED_ISSUER));
+ char *read_buffer;
+ int i, len;
+
+ init_tss_version( credential);
+ credential->capitalALength = read_int( file);
+ read_buffer = read_str( file);
+ credential->capitalA = retrieve_byte_array( &(credential->capitalALength),
+ read_buffer);
+ credential->eLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->e = retrieve_byte_array( &(credential->eLength),read_buffer);
+ credential->vPrimePrimeLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->vPrimePrime = retrieve_byte_array(&(credential->vPrimePrimeLength),
+ read_buffer);
+ // attributes issuer
+ credential->attributesIssuerLength = read_int( file);
+ credential->attributesIssuer = malloc(credential->attributesIssuerLength*sizeof(BYTE*));
+ for( i=0; i < (int)credential->attributesIssuerLength; i++) {
+ credential->attributesIssuer[i] = retrieve_byte_array( &len, read_buffer);
+ }
+ credential->cPrimeLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->cPrime = retrieve_byte_array( &(credential->cPrimeLength),read_buffer);
+ credential->sELength = read_int( file);
+ read_buffer = read_str( file);
+ credential->sE = retrieve_byte_array( &(credential->sELength),read_buffer);
+ return credential;
+}
+
+int
+save_TSS_DAA_CRED_ISSUER(FILE *file, TSS_DAA_CRED_ISSUER *credential)
+{
+ int i;
+
+ fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA");
+ fprintf(file, "%s\n", dump_byte_array( credential->capitalALength,
+ credential->capitalA));
+ fprintf(file, "%d # %s.length\n", credential->eLength, "e");
+ fprintf(file, "%s\n", dump_byte_array( credential->eLength,
+ credential->e));
+ fprintf(file, "%d # %s.length\n", credential->vPrimePrimeLength, "vPrimePrime");
+ fprintf(file, "%s\n", dump_byte_array( credential->vPrimePrimeLength,
+ credential->vPrimePrime));
+ fprintf(file, "%d # %s\n", credential->attributesIssuerLength, "attributesIssuerLength");
+ for( i=0; i < (int)credential->attributesIssuerLength; i++) {
+ fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8,
+ credential->attributesIssuer[i]));
+
+ }
+ fprintf(file, "%d # %s.length\n", credential->cPrimeLength, "cPrime");
+ fprintf(file, "%s\n", dump_byte_array( credential->cPrimeLength,
+ credential->cPrime));
+ fprintf(file, "%d # %s.length\n", credential->sELength, "sE");
+ fprintf(file, "%s\n", dump_byte_array( credential->sELength,
+ credential->sE));
+ return 0;
+}
+
+
+/********************************************************************************************
+ TSS_DAA_CREDENTIAL
+********************************************************************************************/
+
+TSS_DAA_CREDENTIAL *
+load_TSS_DAA_CREDENTIAL(FILE *file)
+{
+ TSS_DAA_CREDENTIAL *credential =
+ (TSS_DAA_CREDENTIAL *)malloc(sizeof(TSS_DAA_CREDENTIAL));
+ char *read_buffer;
+ int i, len;
+ TSS_DAA_PK_internal *pk_internal;
+ TSS_DAA_PK *pk;
+
+ init_tss_version( credential);
+ credential->capitalALength = read_int( file);
+ read_buffer = read_str( file);
+ credential->capitalA = retrieve_byte_array( &(credential->capitalALength),
+ read_buffer);
+ credential->exponentLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->exponent = retrieve_byte_array( &(credential->exponentLength),
+ read_buffer);
+ credential->vBar0Length = read_int( file);
+ read_buffer = read_str( file);
+ credential->vBar0 = retrieve_byte_array(&(credential->vBar0Length),
+ read_buffer);
+ credential->vBar1Length = read_int( file);
+ read_buffer = read_str( file);
+ credential->vBar1 = retrieve_byte_array(&(credential->vBar1Length),
+ read_buffer);
+ // attributes issuer
+ credential->attributesLength = read_int( file);
+ printf("attributesLength=%d\n", credential->attributesLength);
+ credential->attributes = malloc(credential->attributesLength * sizeof( BYTE *));
+ for( i=0; i < (int)credential->attributesLength; i++) {
+ read_buffer = read_str( file);
+ credential->attributes[i] = retrieve_byte_array( &len, read_buffer);
+ if( len != DAA_PARAM_SIZE_F_I / 8) {
+ LogError("Error when parsing attributes");
+ LogError("\tattribute length:%d", len);
+ LogError("\texpected length:%d", DAA_PARAM_SIZE_F_I / 8);
+ return NULL;
+ }
+ }
+ pk_internal = load_DAA_PK_internal( file);
+ pk = i_2_e_TSS_DAA_PK( pk_internal, &normal_malloc, (TSS_HOBJECT)NULL);
+ memcpy( &(credential->issuerPK), pk, sizeof(TSS_DAA_PK));
+ free( pk);
+ free_TSS_DAA_PK_internal( pk_internal);
+ credential->tpmSpecificEncLength = read_int( file);
+ read_buffer = read_str( file);
+ credential->tpmSpecificEnc = retrieve_byte_array( &(credential->tpmSpecificEncLength),
+ read_buffer);
+ credential->daaCounter = read_int( file);
+ return credential;
+}
+
+int
+save_TSS_DAA_CREDENTIAL(FILE *file,
+ TSS_DAA_CREDENTIAL *credential)
+{
+ int i;
+ TSS_DAA_PK_internal *pk_internal;
+
+ fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA");
+ fprintf(file, "%s\n", dump_byte_array( credential->capitalALength,
+ credential->capitalA));
+ fprintf(file, "%d # %s.length\n", credential->exponentLength, "exponent");
+ fprintf(file, "%s\n", dump_byte_array( credential->exponentLength,
+ credential->exponent));
+ fprintf(file, "%d # %s.length\n", credential->vBar0Length, "vBar0");
+ fprintf(file, "%s\n", dump_byte_array( credential->vBar0Length,
+ credential->vBar0));
+ fprintf(file, "%d # %s.length\n", credential->vBar1Length, "vBar1");
+ fprintf(file, "%s\n", dump_byte_array( credential->vBar1Length,
+ credential->vBar1));
+ fprintf(file, "%d # %s\n", credential->attributesLength, "attributesLength");
+ for( i=0; i < (int)credential->attributesLength; i++) {
+ fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8,
+ credential->attributes[i]));
+ }
+ pk_internal = e_2_i_TSS_DAA_PK( &(credential->issuerPK) );
+ save_DAA_PK_internal( file, pk_internal);
+ free_TSS_DAA_PK_internal( pk_internal);
+ fprintf(file, "%d # %s.length\n", credential->tpmSpecificEncLength, "tpmSpecificEnc");
+ fprintf(file, "%s\n", dump_byte_array( credential->tpmSpecificEncLength,
+ credential->tpmSpecificEnc));
+ fprintf(file, "%d # daaCounter\n", credential->daaCounter);
+ return 0;
+}
+#endif
+/********************************************************************************************
+ TPM_DAA_ISSUER
+********************************************************************************************/
+
+void
+free_TPM_DAA_ISSUER(TPM_DAA_ISSUER *tpm_daa_issuer)
+{
+ free(tpm_daa_issuer);
+}
diff --git a/src/tspi/daa/daa_verifier/test/Makefile.am b/src/tspi/daa/daa_verifier/test/Makefile.am
new file mode 100644
index 0000000..aa02721
--- /dev/null
+++ b/src/tspi/daa/daa_verifier/test/Makefile.am
@@ -0,0 +1,7 @@
+bin_PROGRAMS = verifier_transaction
+
+verifier_transaction_SOURCES = ../verifier_transaction.c ../../daa_structs.c \
+ ../../big_integer/bi_gmp.c ../../big_integer/bi_openssl.c ../../big_integer/bi.c \
+ ../../../include/bi.h ../../../include/bi_openssl.h ../../../include/bi_gmp.h \
+ ../../../include/list_.h ../../utils/list.c ../../../include/tss/tss.h ../../../include/daa_parameter.h \
+ ../../../include/daa_structs.h
diff --git a/src/tspi/daa/daa_verifier/verifier.c b/src/tspi/daa/daa_verifier/verifier.c
new file mode 100644
index 0000000..ad7cef1
--- /dev/null
+++ b/src/tspi/daa/daa_verifier/verifier.c
@@ -0,0 +1,57 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bi.h"
+#include "daa_parameter.h"
+#include "trousers/tss.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include <trousers/trousers.h>
+#include <obj.h>
+#include "tsplog.h"
+#include "tss/tcs.h"
+#include "platform.h"
+
+#include "verifier.h"
+
+TSPICALL Tspi_DAA_VerifyInit_internal
+(
+ TSS_HDAA hDAA, // in
+ UINT32* nonceVerifierLength, // out
+ BYTE** nonceVerifier, // out
+ UINT32 baseNameLength, // out
+ BYTE ** baseName // out
+) {
+ TSS_RESULT result = TSS_SUCCESS;
+ TCS_CONTEXT_HANDLE tcsContext;
+ bi_ptr nounce = NULL;
+
+ //TODO how to setup the baseName & baseNameLength
+ if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS)
+ goto close;
+ *nonceVerifierLength = DAA_PARAM_LENGTH_MESSAGE_DIGEST;
+ *nonceVerifier = calloc_tspi( tcsContext, DAA_PARAM_LENGTH_MESSAGE_DIGEST);
+ if (*nonceVerifier == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_LENGTH_MESSAGE_DIGEST);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ nounce = bi_new_ptr();
+ bi_urandom( nounce, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8);
+ bi_2_byte_array( *nonceVerifier, DAA_PARAM_LENGTH_MESSAGE_DIGEST, nounce);
+close:
+ FREE_BI( nounce);
+ return result;
+}
diff --git a/src/tspi/daa/daa_verifier/verifier_transaction.c b/src/tspi/daa/daa_verifier/verifier_transaction.c
new file mode 100644
index 0000000..1eecd43
--- /dev/null
+++ b/src/tspi/daa/daa_verifier/verifier_transaction.c
@@ -0,0 +1,873 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// for message digest
+#include <openssl/evp.h>
+
+#include "daa_structs.h"
+#include "daa_parameter.h"
+#include "trousers/tss.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include <trousers/trousers.h>
+#include <spi_utils.h>
+#include <obj.h>
+#include "tsplog.h"
+#include "tss/tcs.h"
+#include "verifier.h"
+
+#include "trousers/tss.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+
+#include "anonymity_revocation.h"
+
+DAA_VERIFIER_TRANSACTION *create_verifier_transaction( int length, char *base_name) {
+ DAA_VERIFIER_TRANSACTION *verifier_transaction =
+ malloc(sizeof(DAA_VERIFIER_TRANSACTION));
+
+ if (verifier_transaction == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(DAA_VERIFIER_TRANSACTION));
+ return NULL;
+ }
+ verifier_transaction->baseName = base_name;
+ verifier_transaction->baseName_length = length;
+ OpenSSL_add_all_digests();
+ verifier_transaction->digest = DAA_PARAM_get_message_digest();
+ return verifier_transaction;
+}
+
+static int verifyNonce( BYTE *nonce_verifier, int length) {
+ //TODO check nonce_verifier with the current transaction nonce
+ return 1;
+}
+
+BYTE *compute_bytes( int seedLength, BYTE *seed, int length, const EVP_MD *digest) {
+ EVP_MD_CTX mdctx;
+ int N;
+ BYTE *hash;
+ BYTE *result;
+ int i, big_indian_i, len_hash;
+
+ result = (BYTE *)malloc( length);
+ if (result == NULL) {
+ LogError("malloc of %d bytes failed", length);
+ return NULL;
+ }
+ EVP_MD_CTX_init(&mdctx);
+ EVP_DigestInit_ex(&mdctx, digest, NULL);
+ len_hash = EVP_MD_size(digest);
+ N = length / len_hash;
+ hash = (BYTE *)malloc( len_hash);
+ if (hash == NULL) {
+ LogError("malloc of %d bytes failed", len_hash);
+ return NULL;
+ }
+ for( i=0; i<N; i++) {
+ EVP_DigestUpdate(&mdctx, seed, seedLength);
+ big_indian_i = htonl( i);
+ EVP_DigestUpdate(&mdctx, &big_indian_i, sizeof( int));
+ EVP_DigestFinal_ex(&mdctx, &result[ i * len_hash], NULL);
+ EVP_DigestInit_ex(&mdctx, digest, NULL);
+ }
+ // fill up the rest of the array (i=N)
+ EVP_DigestUpdate(&mdctx, seed, seedLength);
+ big_indian_i = htonl( i);
+ EVP_DigestUpdate(&mdctx, &big_indian_i, sizeof( int));
+ EVP_DigestFinal(&mdctx, hash, NULL);
+ // copy the rest: base_nameLength % len_hash bytes
+ memcpy( &result[ i * len_hash], hash, length - N * len_hash);
+ free( hash);
+ return result;
+}
+
+/* from DAAUtil */
+bi_ptr project_into_group_gamma( bi_ptr base, TSS_DAA_PK_internal *issuer_pk) {
+ bi_t exponent; bi_new( exponent);
+ bi_ptr capital_gamma = issuer_pk->capitalGamma;
+ bi_ptr rho = issuer_pk->rho;
+ bi_ptr zeta = bi_new_ptr();
+
+ if( capital_gamma == NULL ||
+ rho == NULL ||
+ zeta == NULL) return NULL;
+ // exponent = capital_gamma - 1
+ bi_sub( exponent, capital_gamma, bi_1);
+ // exponent = exponent / rho
+ bi_div( exponent, exponent, rho);
+ // zeta = ( base ^ exponent) % capital_gamma
+ LogDebug("project_into_group_gamma: rho [%ld]:%s",
+ bi_nbin_size( rho), bi_2_hex_char( rho));
+ LogDebug("project_into_group_gamma: base[%ld]:%s",
+ bi_nbin_size( base), bi_2_hex_char( base));
+ LogDebug("project_into_group_gamma: exponent [%ld]:%s",
+ bi_nbin_size( exponent), bi_2_hex_char( exponent));
+ LogDebug("project_into_group_gamma: capitalGamma[%ld]:%s",
+ bi_nbin_size( capital_gamma),
+ bi_2_hex_char( capital_gamma));
+ bi_mod_exp( zeta, base, exponent, capital_gamma);
+ LogDebug("project_into_group_gamma: result:%s", bi_2_hex_char( zeta));
+ bi_free( exponent);
+ return zeta;
+}
+
+bi_ptr compute_zeta( int nameLength, unsigned char *name, TSS_DAA_PK_internal *issuer_pk) {
+ BYTE *bytes;
+ bi_ptr base;
+ bi_ptr result;
+
+ LogDebug("compute_zeta: %d [%s] pk:%x", nameLength, name, (int)issuer_pk);
+ bytes = compute_bytes( nameLength,
+ name,
+ DAA_PARAM_LENGTH_MFG1_GAMMA,
+ DAA_PARAM_get_message_digest());
+ if( bytes == NULL) return NULL;
+ base = bi_set_as_nbin( DAA_PARAM_LENGTH_MFG1_GAMMA, bytes);
+ if( base == NULL) return NULL;
+ LogDebug("base: %ld [%s]", bi_nbin_size( base), bi_2_hex_char( base));
+ result = project_into_group_gamma( base, issuer_pk);
+ if( result == NULL) return NULL;
+ bi_free_ptr( base);
+ free( bytes);
+ LogDebug("return zeta:%s\n", bi_2_hex_char( result));
+ return result;
+}
+
+bi_ptr compute_parameterized_gamma(int k, TSS_DAA_PK_internal *issuer_pk) {
+ int length;
+ int hashLength = bi_nbin_size( issuer_pk->gamma) + sizeof(int);
+ BYTE *hash;
+ int big_indian_k = htonl( k);
+ BYTE *bytes;
+ bi_ptr value, result;
+
+ hash = (BYTE *)malloc( hashLength);
+ if (hash == NULL) {
+ LogError("malloc of %d bytes failed", hashLength);
+ return NULL;
+ }
+ // hash[0-3] = big_indian(k)
+ memcpy( hash, &big_indian_k, sizeof(int));
+ // hash[4-end] = issuer_pk->gamma
+ bi_2_nbin1( &length, &hash[sizeof(int)], issuer_pk->gamma);
+ // allocation
+ bytes = compute_bytes( hashLength, hash,
+ DAA_PARAM_LENGTH_MFG1_GAMMA,
+ DAA_PARAM_get_message_digest());
+ if( bytes == NULL) return NULL;
+ // allocation
+ value = bi_set_as_nbin( DAA_PARAM_LENGTH_MFG1_GAMMA, bytes);
+ if( value == NULL) return NULL;
+ result = project_into_group_gamma( value, issuer_pk); // allocation
+ if (result == NULL) {
+ LogError("malloc of %d bytes failed", hashLength);
+ return NULL;
+ }
+ bi_free_ptr( value);
+ free( bytes);
+ return result;
+}
+
+inline bi_ptr apply_challenge( bi_ptr value, bi_ptr delta, bi_ptr c, bi_ptr capital_gamma) {
+ bi_ptr delta_tilde = bi_new_ptr();
+ bi_t c_negate;
+
+ if( delta_tilde == NULL) return NULL;
+ bi_new( c_negate);
+ bi_set( c_negate, c);
+ bi_negate( c_negate);
+ // delta_tilde = ( delta ^ (-c)) % capital_gamma
+ bi_mod_exp( delta_tilde, delta, c_negate, capital_gamma);
+ bi_free( c_negate);
+ // delta_tilde = (delta_tilde * value) % capital_gamma
+ return bi_mod( delta_tilde, bi_mul( delta_tilde, delta_tilde, value), capital_gamma);
+}
+
+DAA_VERIFIER_TRANSACTION *createTransaction(int baseName_length, BYTE* baseName) {
+ DAA_VERIFIER_TRANSACTION *result =
+ (DAA_VERIFIER_TRANSACTION *)malloc( sizeof(DAA_VERIFIER_TRANSACTION));
+
+ if (result == NULL) {
+ LogError("malloc of %d bytes failed", sizeof(DAA_VERIFIER_TRANSACTION));
+ return NULL;
+ }
+ result->baseName = baseName;
+ result->baseName_length = baseName_length;
+ return result;
+}
+
+void update( EVP_MD_CTX *mdctx, char *name, bi_ptr integer, int bitLength) {
+ int length = bitLength / 8;
+ BYTE buffer[length];
+
+ bi_2_byte_array( buffer, length, integer);
+ LogDebug("[update] %s:%s", name, dump_byte_array( length, buffer));
+ EVP_DigestUpdate(mdctx, buffer, length);
+}
+
+BYTE *compute_sign_challenge_host(
+ int *result_length,
+ EVP_MD *digest,
+ TSS_DAA_PK_internal *issuer_pk,
+ int nonce_verifierLength,
+ BYTE *nonce_verifier,
+ int selected_attributes2commitLength,
+ TSS_DAA_SELECTED_ATTRIB **selected_attributes2commit,
+ int is_anonymity_revocation_enabled,
+ bi_ptr zeta,
+ bi_ptr capital_t,
+ bi_ptr capital_tilde,
+ int attribute_commitmentsLength,
+ TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitments,
+ TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitment_proofs,
+ bi_ptr capital_nv,
+ bi_ptr capital_tilde_v,
+ CS_PUBLIC_KEY *anonymity_revocator_pk,
+ CS_ENCRYPTION_RESULT *encryption_result_rand,
+ CS_ENCRYPTION_RESULT *encryption_result_proof
+) {
+ EVP_MD_CTX mdctx;
+ int i, length;
+ unsigned int big_indian;
+ BYTE *buffer;
+ int length_gamma_modulus;
+ BYTE *buffer1;
+
+ LogDebug("issuer_pk basename[%d]:%s",
+ issuer_pk->issuerBaseNameLength,
+ dump_byte_array( issuer_pk->issuerBaseNameLength,
+ issuer_pk->issuerBaseName));
+ LogDebug("nonce_verifier[%d]:%s",
+ nonce_verifierLength,
+ dump_byte_array( nonce_verifierLength, nonce_verifier));
+ LogDebug("selected_attributes2commitLength:%d", selected_attributes2commitLength);
+ LogDebug("is_anonymity_revocation_enabled:%d", is_anonymity_revocation_enabled);
+ LogDebug("zeta[%ld]:%s", bi_nbin_size( zeta), bi_2_hex_char( zeta));
+ LogDebug("capital_t[%ld]:%s", bi_nbin_size( capital_t), bi_2_hex_char( capital_t));
+ LogDebug("capital_tilde[%ld]:%s",
+ bi_nbin_size( capital_tilde),
+ bi_2_hex_char( capital_tilde));
+ LogDebug("attribute_commitmentsLength:%d", attribute_commitmentsLength);
+ LogDebug("attribute_commitments:%d", (int)attribute_commitments);
+ LogDebug("attribute_commitment_proofs:%d", (int)attribute_commitment_proofs);
+ LogDebug("capital_nv[%ld]:%s", bi_nbin_size( capital_nv), bi_2_hex_char( capital_nv));
+ LogDebug("capital_tilde_v[%ld]:%s",
+ bi_nbin_size( capital_tilde_v),
+ bi_2_hex_char( capital_tilde_v));
+ LogDebug("anonymity_revocator_pk:%d", (int)anonymity_revocator_pk);
+ LogDebug("encryption_result_rand:%d", (int)encryption_result_rand);
+ LogDebug("encryption_result_proof:%d", (int)encryption_result_proof);
+
+ EVP_MD_CTX_init(&mdctx);
+ EVP_DigestInit_ex(&mdctx, digest, NULL);
+ // update with encoded PK
+ buffer = encoded_DAA_PK_internal( &length, issuer_pk);
+ if( buffer == NULL) return NULL;
+ LogDebug("encoded issuer_pk[%d]:%s", length, dump_byte_array( length, buffer));
+ EVP_DigestUpdate(&mdctx, buffer , length);
+ free( buffer);
+ // nonce verifier
+ EVP_DigestUpdate(&mdctx, nonce_verifier , nonce_verifierLength);
+ // length Commitments
+ big_indian = attribute_commitmentsLength;
+ EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int));
+ // Anonymity enabled
+ big_indian = is_anonymity_revocation_enabled;
+ EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int));
+
+ update( &mdctx, "zeta", zeta, DAA_PARAM_SIZE_MODULUS_GAMMA);
+ update( &mdctx, "capitalT", capital_t, DAA_PARAM_SIZE_RSA_MODULUS);
+ update( &mdctx, "capitalTTilde", capital_tilde, DAA_PARAM_SIZE_RSA_MODULUS);
+
+ length_gamma_modulus = DAA_PARAM_SIZE_MODULUS_GAMMA / 8;
+ buffer = (BYTE *)malloc( length_gamma_modulus);// allocation
+ if (buffer == NULL) {
+ LogError("malloc of %d bytes failed", length_gamma_modulus);
+ return NULL;
+ }
+ if( selected_attributes2commitLength > 0) {
+ for( i=0; i<selected_attributes2commitLength; i++) {
+ buffer1 = to_bytes_TSS_DAA_SELECTED_ATTRIB_internal(
+ &length,
+ selected_attributes2commit[i]);
+ EVP_DigestUpdate(&mdctx, buffer1, length);
+ free( buffer1);
+ bi_2_byte_array( buffer,
+ length_gamma_modulus,
+ attribute_commitments[i]->beta);
+ EVP_DigestUpdate(&mdctx,
+ buffer,
+ length_gamma_modulus);
+ bi_2_byte_array( buffer,
+ length_gamma_modulus,
+ attribute_commitment_proofs[i]->beta);
+ EVP_DigestUpdate(&mdctx,
+ buffer,
+ length_gamma_modulus);
+ }
+ }
+ if( !is_anonymity_revocation_enabled) {
+ // Nv, N~v
+ bi_2_byte_array( buffer, length_gamma_modulus, capital_nv);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, capital_tilde_v);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ } else {
+ bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->eta);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda1);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda2);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda3);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c1);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c2);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c3);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c4);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c1);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c2);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c3);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c4);
+ EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
+ }
+ free(buffer);
+ buffer = (BYTE *)malloc(EVP_MD_size(digest)); // allocation
+ if (buffer == NULL) {
+ LogError("malloc of %d bytes failed", EVP_MD_size(digest));
+ return NULL;
+ }
+ EVP_DigestFinal_ex(&mdctx, buffer, result_length);
+ EVP_MD_CTX_cleanup(&mdctx);
+ LogDebug("compute_sign_challenge_host[%d]:%s",
+ *result_length,
+ dump_byte_array( *result_length, buffer));
+ return buffer;
+}
+
+inline int is_element_gamma( bi_ptr capital_nv, TSS_DAA_PK_internal *issuer_pk) {
+ bi_ptr tmp1 = bi_new_ptr();
+ int result;
+
+ // ( ( capital_nv ^ issuer_pk->rho ) % issuer_pk->capitalGamma ) == 1
+ result = bi_equals( bi_mod_exp( tmp1,
+ capital_nv,
+ issuer_pk->rho,
+ issuer_pk->capitalGamma),
+ bi_1);
+ bi_free_ptr( tmp1);
+ return result;
+}
+
+/* implementation derived from isValid (VerifierTransaction.java) */
+TSPICALL Tspi_DAA_VerifySignature_internal
+( TSS_HDAA hDAA, // in
+ TSS_DAA_SIGNATURE signature_ext, // in
+ TSS_HKEY hPubKeyIssuer, // in
+ TSS_DAA_SIGN_DATA sign_data, // in
+ UINT32 attributesLength, // in
+ BYTE **attributes, // in
+ UINT32 nonce_verifierLength, // out
+ BYTE *nonce_verifier, // out
+ UINT32 base_nameLength, // out
+ BYTE *base_name, // out
+ TSS_BOOL *isCorrect // out
+) {
+ int i, j;
+ DAA_VERIFIER_TRANSACTION *verifier_transaction = NULL;
+ TSS_DAA_ATTRIB_COMMIT *commitments;
+ TSS_DAA_PK_internal *issuer_pk;
+ TSS_DAA_SIGNATURE_internal *signature = NULL;
+ bi_ptr tmp1;
+ bi_array_ptr sA;
+ bi_ptr n = NULL;
+ bi_ptr c = NULL;
+ bi_ptr capital_gamma = NULL;
+ bi_ptr zeta_2_verify = NULL;
+ bi_ptr capital_z = NULL;
+ bi_array_ptr capital_R = NULL;
+ bi_ptr product_r = NULL;
+ bi_ptr exp = NULL;
+ bi_ptr capital_THat = NULL;
+ bi_ptr beta_tilde = NULL;
+ bi_ptr gamma_i = NULL;
+ bi_ptr capital_nv = NULL;
+ bi_ptr capital_ntilde_v = NULL;
+ bi_ptr pseudonym_projected = NULL;
+ bi_ptr s_tau = NULL;
+ bi_ptr delta_tilde1 = NULL;
+ bi_ptr delta_tilde2 = NULL;
+ bi_ptr delta_tilde3 = NULL;
+ bi_ptr delta_tilde4 = NULL;
+ bi_ptr attribute_i;
+ TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain;
+ CS_ENCRYPTION_RESULT *pseudonym_enc = NULL;
+ CS_ENCRYPTION_RESULT *pseudonym_encryption_proof = NULL;
+ TSS_DAA_PSEUDONYM_ENCRYPTED_internal *sig_pseudonym_encrypted = NULL;
+ CS_ENCRYPTION_RESULT_RANDOMNESS *result_random = NULL;
+ CS_ENCRYPTION_RESULT *encryption_result = NULL;
+ TSS_DAA_ATTRIB_COMMIT_internal **commitment_proofs = NULL;
+ TCS_CONTEXT_HANDLE tcsContext;
+ TSS_RESULT result = TSS_SUCCESS;
+ EVP_MD_CTX mdctx;
+ int length_ch, len_hash, bits;
+ BYTE *ch = NULL, *hash = NULL;
+ TSS_BOOL *indices;
+
+ tmp1 = bi_new_ptr();
+ if( tmp1 == NULL) {
+ LogError("malloc of BI <%s> failed", "tmp1");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ *isCorrect = FALSE;
+ if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS)
+ goto close;
+ // allocation of issuer_pk
+ issuer_pk = e_2_i_TSS_DAA_PK( (TSS_DAA_PK *)hPubKeyIssuer);
+ if( issuer_pk == NULL) {
+ LogError("malloc of TSS_DAA_PK_internal failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // allocation of signature
+ signature = e_2_i_TSS_DAA_SIGNATURE( &signature_ext);
+ if( signature == NULL) {
+ LogError("malloc of TSS_DAA_SIGNATURE_internal failed");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ commitments = signature_ext.attributeCommitments;
+ // TODO verify consistency of sig.getSA() with selectedAttributes,..
+ sA = signature->sA;
+ if( sA->length != (int)attributesLength) {
+ LogError("Verifier Error: lengths of attributes and sA must be equal");
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ for ( i = 0; i < (int)attributesLength; i++) {
+ if ( (attributes[i] == NULL && bi_equals( sA->array[i], bi_0)) ||
+ (attributes[i] != NULL && !bi_equals( sA->array[i], bi_0))) {
+ LogError( "Verifier Error: illegal argument content in attributes\
+ and sA[%d]", i);
+ result = TSS_E_BAD_PARAMETER;
+ goto close;
+ }
+ }
+ // TODO: implement verify nonce
+ if ( verifyNonce(nonce_verifier, nonce_verifierLength) == 0) {
+ LogError("Verifier Error: nonce invalid");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ n = issuer_pk->modulus;
+ c = bi_set_as_nbin( signature->challenge_length, signature->challenge);
+ capital_gamma = issuer_pk->capitalGamma;
+ if( base_name != NULL) { // isRandomBaseName
+ zeta_2_verify = compute_zeta( base_nameLength, base_name, issuer_pk);
+ if( bi_equals( signature->zeta, zeta_2_verify) == 0) {
+ LogError("Verifier Error: Verification of zeta failed - Step 1");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ }
+ LogDebug( "step 2");
+ capital_z = issuer_pk->capitalZ;
+ capital_R = issuer_pk->capitalY;
+ product_r = bi_new_ptr();
+ if( product_r == NULL) {
+ LogError("malloc of BI <%s> failed", "product_r");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( product_r, bi_1); // product_r = 1
+ for( i=0; i<(int)attributesLength; i++) {
+ if( attributes[i] != NULL) {
+ // allocation
+ attribute_i = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, attributes[i]);
+ if( attribute_i == NULL) {
+ LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // tmp1 = (capital_R[i] ^ attributes[i]) mod n
+ bi_mod_exp( tmp1, capital_R->array[i], attribute_i, n);
+ // product_r = product_r * tmp1
+ bi_mul( product_r, product_r, tmp1);
+ // product_r = product_r mod n
+ bi_mod( product_r, product_r, n);
+ bi_free_ptr( attribute_i);
+ }
+ }
+ exp = bi_new_ptr();
+ if( exp == NULL) {
+ LogError("malloc of BI <%s> failed", "product_r");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capital_THat = bi_new_ptr();
+ // tmp1 = product_r invmod n
+ bi_invert_mod( tmp1, product_r, n);
+ // capital_THat = capital_z * tmp1
+ bi_mul( capital_THat, capital_z, tmp1);
+ // capital_THat = capital_THat % n
+ bi_mod( capital_THat, capital_THat, n);
+ // capital_THat = (capital_THat ^ (-c)) mod n = ( 1 / (capital_That ^ c) ) % n
+ bi_mod_exp( capital_THat, capital_THat, c, n);
+ bi_invert_mod( capital_THat, capital_THat, n);
+ // tmp1 = c << (SizeExponentCertificate - 1)
+ bi_shift_left( tmp1, c, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1);
+ // exp = signature->sE + tmp1
+ bi_add( exp, signature->sE, tmp1);
+ // tmp1 = (signature->capitalT ^ exp) mod n
+ bi_mod_exp( tmp1, signature->capitalT, exp, n);
+ // capital_THat = ( capital_THat * tmp1 ) % n
+ bi_mul( capital_THat, capital_THat, tmp1);
+ bi_mod( capital_THat, capital_THat, n);
+ // tmp1=( issuer_pk->capitalR0 ^ signature->sF0) % n
+ bi_mod_exp( tmp1, issuer_pk->capitalR0, signature->sF0, n);
+ // capital_THat = ( capital_THat * tmp1 ) % n
+ bi_mul( capital_THat, capital_THat, tmp1);
+ bi_mod( capital_THat, capital_THat, n);
+ // tmp1=( issuer_pk->capitalR1 ^ signature->sF1) % n
+ bi_mod_exp( tmp1, issuer_pk->capitalR1, signature->sF1, n);
+ // capital_THat = ( capital_THat * tmp1 ) % n
+ bi_mul( capital_THat, capital_THat, tmp1);
+ bi_mod( capital_THat, capital_THat, n);
+ // tmp1=( issuer_pk->capitalS ^ signature->sV) % n
+ bi_mod_exp( tmp1, issuer_pk->capitalS, signature->sV, n);
+ // capital_THat = ( capital_THat * tmp1 ) % n
+ bi_mul( capital_THat, capital_THat, tmp1);
+ bi_mod( capital_THat, capital_THat, n);
+
+ bi_set( product_r, bi_1); // product_r = 1
+ for( i=0; i<(int)attributesLength; i++) {
+ if( attributes[i] == NULL) {
+ // tmp1=(capital_R->array[i] ^ sA->array[i]) % n
+ bi_mod_exp( tmp1, capital_R->array[i], sA->array[i], n);
+ // product_r = ( product_r * tmp1 ) % n
+ bi_mul( product_r, product_r, tmp1);
+ bi_mod( product_r, product_r, n);
+ }
+ }
+ // capital_THat = (capital_THat * product_r) % n
+ bi_mod( capital_THat, bi_mul( tmp1, capital_THat, product_r), n);
+ LogDebug("Step 3 - Commitments");
+
+ //TODO when enabling the commitment feature, verifier_transaction should be set
+ #ifdef ANONYMITY_REVOCATION
+ if( verifier_transaction != NULL &&
+ verifier_transaction->selected_attributes2commitLength > 0) {
+ commitment_proofs = (TSS_DAA_ATTRIB_COMMIT_internal **)
+ malloc(verifier_transaction->selected_attributes2commitLength *
+ sizeof(TSS_DAA_ATTRIB_COMMIT_internal*));
+ if (commitment_proofs == NULL) {
+ LogError("malloc of %d bytes failed",
+ verifier_transaction->selected_attributes2commitLength *
+ sizeof(TSS_DAA_ATTRIB_COMMIT_internal*));
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ for( j=0; j<verifier_transaction->selected_attributes2commitLength; j++) {
+ if( bi_cmp( commitments[j].sMu, issuer_pk->rho) >= 0 ||
+ bi_cmp_si( commitments[j].sMu, 0) < 0) {
+ LogError("sMu >= rho || sMu < 0");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ beta_tilde = bi_new_ptr();
+ if( beta_tilde == NULL) {
+ LogError("malloc of BI <%s> failed", "beta_tilde");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_set( tmp1, c);
+ bi_negate( tmp1);
+ // beta_tilde=(commitments[j]->beta ^ (-c)) % capitalGamma
+ bi_mod_exp( beta_tilde, commitments[j]->beta, tmp1, capital_gamma);
+ // tmp1=(issuer_pk->gamma ^ commitments[j]->sMu) % capital_gamma
+ bi_mod_exp( tmp1, issuer_pk->gamma, commitments[j]->sMu, capital_gamma);
+ // beta_tilde=beta_tilde * tmp1
+ bi_mul( beta_tilde, beta_tilde, tmp1);
+ // beta_tilde=beta_tilde % capital_gamma
+ bi_mod( beta_tilde, beta_tilde, capital_gamma);
+ indices = (verifier_transaction->selected_attributes2commit[j])->
+ indicesList;
+ if( verifier_transaction->selected_attributes2commit[j]->
+ indicesListLength != (UINT32)(issuer_pk->capitalY->length) ) {
+ LogError("indicesList of selected_attribs[%d] (%d) \
+and issuer_pk are not consistent (%d)\n",
+ j,
+ verifier_transaction->selected_attributes2commit[j]->
+ indicesListLength,
+ issuer_pk->capitalY->length);
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ for( i=0; i<issuer_pk->capitalY->length; i++) {
+ if( indices[i]) {
+ gamma_i = compute_parameterized_gamma( i, issuer_pk);
+ if( gamma_i == NULL) {
+ LogError("malloc of BI <%s> failed", "gamma_i");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ // tmp1=(gamma_i ^ sA[j]) % capital_gamma
+ bi_mod_exp( tmp1, gamma_i, sA->array[i], capital_gamma);
+ // beta_tilde=beta_tilde * tmp1
+ bi_mul( beta_tilde, beta_tilde, tmp1);
+ // beta_tilde=beta_tilde % capital_gamma
+ bi_mod( beta_tilde, beta_tilde, capital_gamma);
+ }
+ }
+ commitment_proofs[j] = create_TSS_DAA_ATTRIB_COMMIT( beta_tilde, NULL);
+ }
+ }
+ #endif
+ LogDebug("Step 4 - Pseudonym");
+ capital_nv = bi_new_ptr();
+ if( capital_nv == NULL) {
+ LogError("malloc of BI <%s> failed", "capital_nv");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ capital_ntilde_v = bi_new_ptr();
+ if( capital_ntilde_v == NULL) {
+ LogError("malloc of BI <%s> failed", "capital_ntilde_v");
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ bi_shift_left( tmp1, signature->sF1, DAA_PARAM_SIZE_F_I);
+ bi_add( exp, signature->sF0, tmp1);
+ pseudonym_projected = bi_new_ptr();
+ // pseudonym_projected = (signature->zeta ^ exp) % capital_gamma
+ bi_mod_exp( pseudonym_projected, signature->zeta, exp, capital_gamma);
+ pseudonym_enc = NULL;
+ pseudonym_encryption_proof = NULL;
+ //TODO when enabling the commitment feature, verifier_transaction should be set
+ if( verifier_transaction == NULL ||
+ verifier_transaction->is_anonymity_revocation_enabled ==0) {
+ // anonymity revocation not enabled
+ pseudonym_plain = (TSS_DAA_PSEUDONYM_PLAIN *)signature_ext.signedPseudonym;
+ capital_nv = bi_set_as_nbin( pseudonym_plain->capitalNvLength,
+ pseudonym_plain->capitalNv);
+//TODO
+ // capital_ntilde_v = ( capital_nv ^ ( - c) ) % capital_gamma
+ // = ( 1 / (capital_nv ^ c) % capital_gamma) % capital_gamma
+ bi_mod_exp( tmp1, capital_nv, c, capital_gamma);
+ bi_invert_mod( capital_ntilde_v, tmp1, capital_gamma);
+ // capital_ntilde_v = ( capital_ntilde_v * pseudonym_projected ) % capital_gamma
+ bi_mul(capital_ntilde_v, capital_ntilde_v, pseudonym_projected);
+ bi_mod( capital_ntilde_v, capital_ntilde_v, capital_gamma);
+ } else {
+#ifdef ANONYMITY_REVOCATION
+ // anonymity revocation enabled
+ sig_pseudonym_encrypted = (TSS_DAA_PSEUDONYM_ENCRYPTED_internal *)pseudonym;
+ s_tau = sig_pseudonym_encrypted->sTau;
+ pseudonym_enc = sig_pseudonym_encrypted->cs_enc_result;
+ // Note: It verifies if s_tau <= rho
+ result_random = compute_ecryption_proof(
+ pseudonym_projected,
+ pseudonym_enc->c1,
+ pseudonym_enc->c2,
+ pseudonym_enc->c3,
+ s_tau,
+ verifier_transaction->anonymity_revocator_pk, issuer_pk,
+ verifier_transaction->anonymity_revocation_condition,
+ verifier_transaction->anonymity_revocation_condition_length,
+ DAA_PARAM_get_message_digest() );
+ encryption_result = result_random->result;
+ delta_tilde1 = apply_challenge( encryption_result->c1,
+ pseudonym_enc->c1,
+ c,
+ capital_gamma);
+ delta_tilde2 = apply_challenge( encryption_result->c2,
+ pseudonym_enc->c2,
+ c,
+ capital_gamma);
+ delta_tilde3 = apply_challenge( encryption_result->c3,
+ pseudonym_enc->c3,
+ c,
+ capital_gamma);
+ delta_tilde4 = apply_challenge( encryption_result->c4,
+ pseudonym_enc->c4,
+ c,
+ capital_gamma);
+ pseudonym_encryption_proof = create_CS_ENCRYPTION_RESULT( delta_tilde1,
+ delta_tilde2,
+ delta_tilde3,
+ delta_tilde4);
+#endif
+ }
+
+ // TODO: Step 5 - Callback
+ LogDebug("Step 5 - Callback");
+
+ LogDebug("Step 6 - Hash");
+ ch = compute_sign_challenge_host(
+ &length_ch,
+ DAA_PARAM_get_message_digest(),
+ issuer_pk,
+ nonce_verifierLength,
+ nonce_verifier,
+ 0, // verifier_transaction->selected_attributes2commitLength,
+ NULL, //verifier_transaction->selected_attributes2commit,
+ 0, // verifier_transaction->is_anonymity_revocation_enabled,
+ signature->zeta,
+ signature->capitalT,
+ capital_THat,
+ 0, //signature_ext.attributeCommitmentsLength,
+ NULL, // signature_ext.attributeCommitments,
+ commitment_proofs,
+ capital_nv,
+ capital_ntilde_v,
+ NULL, // verifier_transaction->anonymity_revocator_pk,
+ pseudonym_enc,
+ pseudonym_encryption_proof);
+ LogDebug("calculation of c: ch[%d]%s", length_ch, dump_byte_array( length_ch, ch));
+ LogDebug("calculation of c: nonce_tpm[%d]%s",
+ signature->nonce_tpm_length,
+ dump_byte_array( signature->nonce_tpm_length, signature->nonce_tpm));
+ LogDebug("calculation of c: sign_data.payloadFlag[%d]%x", 1, sign_data.payloadFlag);
+ LogDebug("calculation of c: signdata.payload[%d]%s",
+ sign_data.payloadLength,
+ dump_byte_array( sign_data.payloadLength, sign_data.payload));
+ EVP_MD_CTX_init(&mdctx);
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ EVP_DigestUpdate(&mdctx, ch, length_ch);
+ EVP_DigestUpdate(&mdctx, signature->nonce_tpm, signature->nonce_tpm_length);
+ len_hash = EVP_MD_size( DAA_PARAM_get_message_digest());
+ hash = (BYTE *)malloc( len_hash);// allocation
+ if (hash == NULL) {
+ LogError("malloc of %d bytes failed", len_hash);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ EVP_DigestFinal_ex(&mdctx, hash, NULL);
+ EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL);
+ EVP_DigestUpdate(&mdctx, hash, EVP_MD_size( DAA_PARAM_get_message_digest()));
+ EVP_DigestUpdate(&mdctx, &sign_data.payloadFlag, 1);
+ EVP_DigestUpdate(&mdctx, sign_data.payload, sign_data.payloadLength);
+ len_hash = EVP_MD_size( DAA_PARAM_get_message_digest());
+ free( hash);
+ hash = (BYTE *)malloc( len_hash);// allocation
+ if (hash == NULL) {
+ LogError("malloc of %d bytes failed", len_hash);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto close;
+ }
+ EVP_DigestFinal(&mdctx, hash, NULL);
+
+ if( signature->challenge_length != len_hash ||
+ memcmp( signature->challenge, hash, len_hash) != 0) {
+ LogError( "Verification of c failed - Step 6.c.i");
+ LogError(" - challenge[%d] : %s",
+ signature->challenge_length,
+ dump_byte_array( signature->challenge_length, signature->challenge));
+ LogError(" - hash[%d] : %s",
+ len_hash,
+ dump_byte_array( len_hash, hash));
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ if( verifier_transaction == NULL ||
+ !verifier_transaction->is_anonymity_revocation_enabled) {
+ // Nv element <gamma> ?
+ if( !is_element_gamma( capital_nv, issuer_pk) ) {
+ LogError( "Verification of Nv failed - Step 4.b.i");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ } else {
+ // are delta1-4 element <gamma> ?
+ if( !( is_element_gamma( pseudonym_enc->c1, issuer_pk) &&
+ is_element_gamma( pseudonym_enc->c2, issuer_pk) &&
+ is_element_gamma( pseudonym_enc->c3, issuer_pk) &&
+ is_element_gamma( pseudonym_enc->c4, issuer_pk))) {
+ LogError( "Verification of delta1-4 failed - Step 4.c.i");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ }
+ // zeta element <gamma>
+ if( !is_element_gamma( signature->zeta, issuer_pk)) {
+ LogError( "Verification of zeta failed - Step 4.b/c.i");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ bits = DAA_PARAM_SIZE_F_I + DAA_PARAM_SAFETY_MARGIN +
+ DAA_PARAM_SIZE_MESSAGE_DIGEST + 1;
+ if( bi_length( signature->sF0) > bits) {
+ LogError("Verification of sF0 failed - Step 6.c.ii");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ if( bi_length( signature->sF1) > bits) {
+ LogError("Verification of sF1 failed - Step 6.c.ii");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ // attributes extension
+ for( i=0; i<sA->length; i++) {
+ if( sA->array[i] != NULL && bi_length(sA->array[i]) > bits) {
+ LogError( "Verification of sA[%d] failed - Step 6.c.ii", i);
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ }
+ bits = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE +
+ DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST + 1;
+ if( bi_length( signature->sE) > bits) {
+ LogError("Verification of sE failed - Step 6.c.iii");
+ result = TSS_E_INTERNAL_ERROR;
+ goto close;
+ }
+ // step 4
+ // TODO: implement revocation list
+ *isCorrect = TRUE;
+close:
+ bi_free_ptr( tmp1);
+ if( ch != NULL) free( ch);
+ if( hash != NULL) free( hash);
+ free_TSS_DAA_PK_internal( issuer_pk);
+ free_TSS_DAA_SIGNATURE_internal( signature);
+ // n not allocated, refere to issuer_pk->modulus
+ FREE_BI( c);
+ // capital_gamma not allocated, refere to issuer_pk->capitalGamma
+ FREE_BI( zeta_2_verify);
+ // capital_z not allocated, refere to issuer_pk->capitalZ
+ // capital_R not allocated, refere to issuer_pk->capitalY
+ FREE_BI( product_r);
+ FREE_BI( exp);
+ FREE_BI( capital_THat);
+ // beta_tilde kept on TSS_DAA_ATTRIB_COMMIT
+ FREE_BI( gamma_i);
+ FREE_BI( capital_nv);
+ FREE_BI( capital_ntilde_v);
+ FREE_BI( pseudonym_projected);
+ FREE_BI( s_tau);
+ // delta_tilde1 kept on CS_ENCRYPTION_RESULT
+ // delta_tilde2 kept on CS_ENCRYPTION_RESULT
+ // delta_tilde3 kept on CS_ENCRYPTION_RESULT
+ // delta_tilde4 kept on CS_ENCRYPTION_RESULT
+ return result;
+}
diff --git a/src/tspi/daa/test_sign.c b/src/tspi/daa/test_sign.c
new file mode 100644
index 0000000..2b13791
--- /dev/null
+++ b/src/tspi/daa/test_sign.c
@@ -0,0 +1,238 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2006
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "daa_structs.h"
+#include "trousers/tss.h"
+#include "trousers/trousers.h"
+#include "spi_internal_types.h"
+#include "spi_utils.h"
+#include "obj.h"
+#include "tsplog.h"
+#include "daa_parameter.h"
+#include "verifier.h"
+#include "platform.h"
+
+// for RSA Key
+#include <openssl/rsa.h>
+
+#define DEFAULT_CREDENTIAL_FILENAME "credential.txt"
+#define DEFAULT_OWN_PASSWD "OWN_PWD"
+
+int print_usage(char *exec) {
+ fprintf(stderr, "usage: %s\n", exec);
+ fprintf(stderr,
+ "\t-m,\t--message\n\t\tif define, the data is signed using this message\n\
+\t\totherwise an AIK will be generated and used\n");
+ fprintf(stderr,
+ "\t-pw,\t--passwd\n\t\ttpm owner password (default: %s)\n",
+ DEFAULT_OWN_PASSWD);
+ fprintf(stderr,
+ "\t-cr,\t--credential\n\t\tcredential filename (default: %s)\n",
+ DEFAULT_CREDENTIAL_FILENAME);
+ return -1;
+}
+
+int main(int argc, char *argv[]) {
+ TSS_HCONTEXT hContext;
+ TSS_RESULT result;
+ TSS_HTPM hTPM;
+ TSS_HPOLICY hPolicy;
+ char *credential_filename = DEFAULT_CREDENTIAL_FILENAME;
+ UINT32 nonceVerifierLength;
+ BYTE *nonceVerifier;
+ TSS_HDAA hDAA;
+ TSS_DAA_CREDENTIAL *hDaaCredential;
+ TSS_DAA_SIGN_DATA signData;
+ TSS_DAA_SIGNATURE daaSignature;
+ TSS_DAA_SELECTED_ATTRIB revealAttributes;
+ char *szTpmPasswd = DEFAULT_OWN_PASSWD;
+ char *message = NULL;
+ BYTE **attributes = NULL;
+ FILE *file;
+ char *param;
+ int i, length, rv;
+ bi_ptr random = NULL;
+ TSS_BOOL isCorrect;
+ EVP_MD_CTX mdctx;
+ TSS_HKEY hKEY;
+
+ init_tss_version( &signData);
+ init_tss_version( &daaSignature);
+ init_tss_version( &revealAttributes);
+ i = 1;
+ while( i < argc) {
+ param = argv[ i];
+ if ( strcmp( param, "-m") == 0 || strcmp( param, "--message") == 0) {
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ message = argv[i];
+ } else if( strcmp( param, "-cr") == 0 || strcmp( param, "--credential") == 0){
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ credential_filename = argv[i];
+ } else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){
+ i++;
+ if( i == argc) return print_usage( argv[0]);
+ szTpmPasswd = argv[i];
+ } else {
+ fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param);
+ return print_usage( argv[0]);
+ }
+ i++;
+ }
+ bi_init( NULL);
+ printf("Loading credential: %s ", credential_filename);
+ file = fopen( credential_filename, "r");
+ if( (hDaaCredential = load_TSS_DAA_CREDENTIAL( file)) == 0) {
+ LogError( "[test_join]: Error when loading \'%s\': %s\n",
+ credential_filename,
+ strerror( errno));
+ result = TSS_E_FAIL;
+ goto out_close;
+ }
+ fclose( file);
+ printf("Done\n");
+
+ // Create Context
+ LogDebug("Create Context");
+ result = Tspi_Context_Create( &hContext );
+ if ( result != TSS_SUCCESS )
+ {
+ LogError( "Tspi_Context_Create %d\n", result );
+ goto out;
+ }
+ // Connect to Context
+ result = Tspi_Context_Connect( hContext, NULL );
+ if ( result != TSS_SUCCESS) goto out_close;
+ printf("\nConnect to the context: %X\n", hContext);
+
+ if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS)
+ goto out_close;
+ // Get the correct policy using the TPM ownership PASSWD
+ if( (result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hPolicy)) != TSS_SUCCESS)
+ goto out_close;
+ if( (result = Tspi_Policy_SetSecret( hPolicy,
+ TSS_SECRET_MODE_PLAIN,
+ strlen( szTpmPasswd),
+ szTpmPasswd)) != TSS_SUCCESS)
+ goto out_close;
+ LogDebug("Tspi_Policy_SetSecret hPolicy received;%d", hPolicy);
+
+ //Create Object
+ result = obj_daa_add( hContext, &hDAA);
+ if (result != TSS_SUCCESS) {
+ LogError("Tspi_Context_CreateObject:%d", result);
+ Tspi_Context_Close(hContext);
+ LogError("%s: %s", argv[0], err_string(result));
+ exit(result);
+ }
+ LogDebug("created DAA object:%X", hDAA);
+
+ // TODO: verifier base name ??
+ result = Tspi_DAA_VerifyInit(
+ hDAA, // in
+ &nonceVerifierLength, // out
+ &nonceVerifier, // out
+ 0, //baseNameLength, // out
+ NULL //baseName // out
+ );
+ if (result != TSS_SUCCESS) goto out_close;
+ LogDebug("Verify Init return nonceVerifier [%s]",
+ dump_byte_array( nonceVerifierLength, nonceVerifier));
+
+ create_TSS_DAA_SELECTED_ATTRIB( &revealAttributes, 5, 0, 1, 1, 0, 0);
+
+ // create the TSS_DAA_SIGN_DATA struct
+ // .selector: 0 -> payload contains a handle to an AIK
+ // 1 -> payload contains a hashed message
+ if( message != NULL) {
+ signData.selector = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
+ signData.payloadFlag = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
+ EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
+ EVP_DigestUpdate(&mdctx, (BYTE *)message, strlen( message));
+ signData.payloadLength = EVP_MD_CTX_size(&mdctx);
+ signData.payload = (BYTE *)malloc( EVP_MD_CTX_size(&mdctx));
+ EVP_DigestFinal(&mdctx, signData.payload, NULL);
+ } else {
+ signData.selector = TSS_FLAG_DAA_SIGN_IDENTITY_KEY;
+ result = Tspi_Context_CreateObject(
+ hContext, // in
+ TSS_OBJECT_TYPE_RSAKEY, // in
+ TSS_KEY_SIZE_2048, // in
+ &hKEY // out
+ );
+ if( result != TSS_SUCCESS) goto out_close;
+
+ }
+
+ result = Tspi_TPM_DAA_Sign(
+ hDAA, // in
+ hTPM, // in
+ (TSS_HKEY)hDaaCredential, // in
+ revealAttributes, // in
+ 0, // verifierBaseNameLength, // in
+ NULL, // verifierBaseName, // in
+ nonceVerifierLength, // in
+ nonceVerifier, // in
+ signData, // in
+ &daaSignature // out
+ );
+ if (result != TSS_SUCCESS) goto out_close;
+ LogDebug("TPM_DAA_Sign return daaSignature [%s]",
+ dump_byte_array( nonceVerifierLength, nonceVerifier));
+
+ // generate attributes list but without copying the not revealed ones
+ attributes = malloc( sizeof(BYTE *) * hDaaCredential->attributesLength);
+ for( i=0; i < (int)(hDaaCredential->attributesLength); i++) {
+ if( revealAttributes.indicesList[i]) {
+ attributes[i] = (BYTE *)malloc( DAA_PARAM_SIZE_F_I / 8);
+ memcpy( attributes[i],
+ hDaaCredential->attributes[i],
+ DAA_PARAM_SIZE_F_I / 8);
+ } else {
+ attributes[i] = NULL;
+ }
+ }
+
+ result = Tspi_DAA_VerifySignature(
+ hDAA, // in
+ daaSignature, // in
+ (TSS_HKEY)&(hDaaCredential->issuerPK), // in
+ signData, // in
+ hDaaCredential->attributesLength, // in
+ attributes, // in
+ nonceVerifierLength, // in
+ nonceVerifier, // in
+ 0, //baseNameLength, //in
+ NULL, // in
+ &isCorrect // out
+ );
+ printf("Signature correct:%s\n", ( isCorrect ? "yes" : "no"));
+
+out_close:
+ if( attributes != NULL) {
+ for( i=0; i<(int)hDaaCredential->attributesLength; i++) {
+ if( attributes[i] != NULL) free( attributes[i]);
+ }
+ free( attributes);
+ }
+ if( random != NULL) bi_free_ptr( random);
+ Tspi_Context_FreeMemory( hContext, NULL );
+ Tspi_Context_Close( hContext );
+out:
+ bi_release();
+ LogDebug("THE END result=%d:%s",result, err_string( result) );;
+ return result;
+}
+
diff --git a/src/tspi/daa/utils/list.c b/src/tspi/daa/utils/list.c
new file mode 100644
index 0000000..634129b
--- /dev/null
+++ b/src/tspi/daa/utils/list.c
@@ -0,0 +1,66 @@
+
+/*
+* Licensed Materials - Property of IBM
+*
+* trousers - An open source TCG Software Stack
+*
+* (C) Copyright International Business Machines Corp. 2006
+*
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <list.h>
+
+#include "tsplog.h"
+
+list_ptr list_new( void) {
+ list_ptr list = (list_ptr)malloc( sizeof( list_struct));
+
+ if( list == NULL) return NULL;
+ list->head = NULL;
+ return list;
+}
+
+void list_add(list_ptr list, void *obj) {
+ list->current = (node_t *) malloc (sizeof(struct _list_t));
+ if (list->current == NULL) {
+ LogError("[list_add] malloc of %d bytes failed", sizeof(struct _list_t));
+ return;
+ }
+ if( list->head == NULL) {
+ list->head = list->current;
+ } else
+ list->previous->next = list->current;
+ list->current->obj = obj;
+ list->current->next = NULL;
+ list->previous = list->current;
+}
+
+void list_dump(list_ptr list) {
+ node_t *current;
+
+ if( list->head == NULL) // if head has not been altered
+ puts("no data"); // list is empty
+ else {
+ current = list->head; // go to first node
+ do {
+ printf("%d\n", (int)current->obj); // print value at current node
+ current = current->next; // traverse through the list
+ } while(current != NULL); // until current node is NULL
+ }
+}
+
+void list_freeall(list_ptr list) {
+ node_t *current = list->head; // go to first node
+ node_t *next;
+
+ if( list->head != NULL) {
+ current = list->head; // go to first node
+ do {
+ next = current->next;
+ free(current);
+ current = next;
+ } while(current != NULL); // until current node is NULL
+ }
+}