1 /* Software-based Trusted Platform Module (TPM) Emulator
2  * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
3  *               2005-2008 Heiko Stamer <stamer@gaos.org>
4  *
5  * This module is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published
7  * by the Free Software Foundation; either version 2 of the License,
8  * or (at your option) any later version.
9  *
10  * This module is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * $Id: tpm_daa.c 452 2010-07-19 19:05:05Z mast $
16  */
17 
18 #include "tpm_emulator.h"
19 #include "tpm_commands.h"
20 #include "tpm_data.h"
21 #include "tpm_handles.h"
22 #include "tpm_marshalling.h"
23 #include "crypto/sha1.h"
24 #include "crypto/rsa.h"
25 #include "crypto/rc4.h"
26 #include "crypto/hmac.h"
27 
28 #define DAA_LABEL_00 ((uint8_t*)"\x00")
29 #define DAA_LABEL_01 ((uint8_t*)"\x01")
30 #define DAA_LABEL_r0 ((uint8_t*)"r0")
31 #define DAA_LABEL_r1 ((uint8_t*)"r1")
32 #define DAA_LABEL_r2 ((uint8_t*)"r2")
33 
tpm_get_free_daa_session(void)34 UINT32 tpm_get_free_daa_session(void)
35 {
36   UINT32 i;
37 
38   for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) {
39     if (tpmData.stany.data.sessionsDAA[i].type == TPM_ST_INVALID) {
40       tpmData.stany.data.sessionsDAA[i].type = TPM_ST_DAA;
41       tpmData.stany.data.sessionsDAA[i].handle = INDEX_TO_DAA_HANDLE(i);
42       return INDEX_TO_DAA_HANDLE(i);
43     }
44   }
45   return TPM_INVALID_HANDLE;
46 }
47 
48 /* Verify that DAA_session->DAA_digestContext ==
49  * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error on mismatch */
tpm_daa_verify_digestContext(TPM_DAA_SESSION_DATA * session,tpm_sha1_ctx_t * sha1)50 static TPM_RESULT tpm_daa_verify_digestContext(TPM_DAA_SESSION_DATA *session,
51                                                tpm_sha1_ctx_t *sha1)
52 {
53   TPM_DIGEST dgt;
54   UINT32 size, len;
55   BYTE *buf, *ptr;
56 
57   tpm_sha1_init(sha1);
58 
59   size = len = sizeof(TPM_DAA_TPM);
60   buf = ptr = tpm_malloc(size);
61   if (buf == NULL)
62     return -1;
63   memset(buf, 0, size);
64   if (tpm_marshal_TPM_DAA_TPM(&ptr, &len, &session->DAA_tpmSpecific)) {
65     tpm_free(buf);
66     return -1;
67   }
68   tpm_sha1_update(sha1, buf, size);
69   tpm_free(buf);
70 
71   size = len = sizeof(TPM_DAA_JOINDATA);
72   buf = ptr = tpm_malloc(size);
73   if (buf == NULL)
74     return -1;
75   memset(buf, 0, size);
76   if (tpm_marshal_TPM_DAA_JOINDATA(&ptr, &len, &session->DAA_joinSession)) {
77     tpm_free(buf);
78     return -1;
79   }
80   tpm_sha1_update(sha1, buf, size);
81   tpm_free(buf);
82 
83   tpm_sha1_final(sha1, dgt.digest);
84 
85   return memcmp(dgt.digest, session->DAA_session.DAA_digestContext.digest,
86     sizeof(TPM_DIGEST));
87 }
88 
89 /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific ||
90  * DAA_joinSession) */
tpm_daa_update_digestContext(TPM_DAA_SESSION_DATA * session,tpm_sha1_ctx_t * sha1)91 static void tpm_daa_update_digestContext(TPM_DAA_SESSION_DATA *session,
92                                          tpm_sha1_ctx_t *sha1)
93 {
94   UINT32 size, len;
95   BYTE *buf, *ptr;
96 
97   tpm_sha1_init(sha1);
98 
99   /* DAA_tpmSpecific */
100   size = len = sizeof(TPM_DAA_TPM);
101   buf = ptr = tpm_malloc(size);
102   if (buf == NULL)
103     return;
104   memset(buf, 0, size);
105   if (tpm_marshal_TPM_DAA_TPM(&ptr, &len, &session->DAA_tpmSpecific)) {
106     tpm_free(buf);
107     return;
108   }
109   tpm_sha1_update(sha1, buf, size);
110   tpm_free(buf);
111 
112   /* DAA_joinSession */
113   size = len = sizeof(TPM_DAA_JOINDATA);
114   buf = ptr = tpm_malloc(size);
115   if (buf == NULL)
116     return;
117   memset(buf, 0, size);
118   if (tpm_marshal_TPM_DAA_JOINDATA(&ptr, &len, &session->DAA_joinSession)) {
119     tpm_free(buf);
120     return;
121   }
122   tpm_sha1_update(sha1, buf, size);
123   tpm_free(buf);
124 
125   tpm_sha1_final(sha1, session->DAA_session.DAA_digestContext.digest);
126 }
127 
128 /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific) and
129  * return error on mismatch */
tpm_daa_verify_digestContext_sign(TPM_DAA_SESSION_DATA * session,tpm_sha1_ctx_t * sha1)130 static TPM_RESULT tpm_daa_verify_digestContext_sign(TPM_DAA_SESSION_DATA *session,
131                                                     tpm_sha1_ctx_t *sha1)
132 {
133   TPM_DIGEST dgt;
134   UINT32 size, len;
135   BYTE *buf, *ptr;
136 
137   tpm_sha1_init(sha1);
138 
139   size = len = sizeof(TPM_DAA_TPM);
140   buf = ptr = tpm_malloc(size);
141   if (buf == NULL)
142     return -1;
143   memset(buf, 0, size);
144   if (tpm_marshal_TPM_DAA_TPM(&ptr, &len, &session->DAA_tpmSpecific)) {
145     tpm_free(buf);
146     return -1;
147   }
148   tpm_sha1_update(sha1, buf, size);
149   tpm_free(buf);
150 
151   tpm_sha1_final(sha1, dgt.digest);
152 
153   return memcmp(dgt.digest, session->DAA_session.DAA_digestContext.digest,
154     sizeof(TPM_DIGEST));
155 }
156 
157 /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific) */
tpm_daa_update_digestContext_sign(TPM_DAA_SESSION_DATA * session,tpm_sha1_ctx_t * sha1)158 static void tpm_daa_update_digestContext_sign(TPM_DAA_SESSION_DATA *session,
159                                               tpm_sha1_ctx_t *sha1)
160 {
161   UINT32 size, len;
162   BYTE *buf, *ptr;
163 
164   tpm_sha1_init(sha1);
165 
166   size = len = sizeof(TPM_DAA_TPM);
167   buf = ptr = tpm_malloc(size);
168   if (buf == NULL)
169     return;
170   memset(buf, 0, size);
171   if (tpm_marshal_TPM_DAA_TPM(&ptr, &len, &session->DAA_tpmSpecific)) {
172     tpm_free(buf);
173     return;
174   }
175   tpm_sha1_update(sha1, buf, size);
176   tpm_free(buf);
177 
178   tpm_sha1_final(sha1, session->DAA_session.DAA_digestContext.digest);
179 }
180 
181 /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
182  * SHA-1(DAA_issuerSettings) and return error on mismatch */
tpm_daa_verify_digestIssuer(TPM_DAA_SESSION_DATA * session,tpm_sha1_ctx_t * sha1)183 static TPM_RESULT tpm_daa_verify_digestIssuer(TPM_DAA_SESSION_DATA *session,
184                                               tpm_sha1_ctx_t *sha1)
185 {
186   TPM_DIGEST dgt;
187   UINT32 size, len;
188   BYTE *buf, *ptr;
189 
190   tpm_sha1_init(sha1);
191 
192   size = len = sizeof(TPM_DAA_ISSUER);
193   buf = ptr = tpm_malloc(size);
194   if (buf == NULL)
195     return -1;
196   memset(buf, 0, size);
197   if (tpm_marshal_TPM_DAA_ISSUER(&ptr, &len, &session->DAA_issuerSettings)) {
198     tpm_free(buf);
199     return -1;
200   }
201   tpm_sha1_update(sha1, buf, size);
202   tpm_free(buf);
203 
204   tpm_sha1_final(sha1, dgt.digest);
205 
206   return memcmp(dgt.digest, session->DAA_tpmSpecific.DAA_digestIssuer.digest,
207     sizeof(TPM_DIGEST));
208 }
209 
210 /* Set DAA_tpmSpecific->DAA_digestIssuer == SHA-1(DAA_issuerSettings) */
tpm_daa_update_digestIssuer(TPM_DAA_SESSION_DATA * session,tpm_sha1_ctx_t * sha1)211 static void tpm_daa_update_digestIssuer(TPM_DAA_SESSION_DATA *session,
212                                         tpm_sha1_ctx_t *sha1)
213 {
214   UINT32 size, len;
215   BYTE *buf, *ptr;
216 
217   tpm_sha1_init(sha1);
218 
219   size = len = sizeof(TPM_DAA_ISSUER);
220   buf = ptr = tpm_malloc(size);
221   if (buf == NULL)
222     return;
223   memset(buf, 0, size);
224   if (tpm_marshal_TPM_DAA_ISSUER(&ptr, &len, &session->DAA_issuerSettings)) {
225     tpm_free(buf);
226     return;
227   }
228   tpm_sha1_update(sha1, buf, size);
229   tpm_free(buf);
230 
231   tpm_sha1_final(sha1, session->DAA_tpmSpecific.DAA_digestIssuer.digest);
232 }
233 
234 /* Verify that SHA-1(input) == digest and return error !TPM_SUCCESS
235  * on mismatch */
tpm_daa_verify_generic(TPM_DIGEST digest,BYTE * input,UINT32 inputSize,tpm_sha1_ctx_t * sha1)236 static TPM_RESULT tpm_daa_verify_generic(TPM_DIGEST digest, BYTE *input,
237                                          UINT32 inputSize, tpm_sha1_ctx_t *sha1)
238 {
239   TPM_DIGEST dgt;
240 
241   tpm_sha1_init(sha1);
242   tpm_sha1_update(sha1, input, inputSize);
243   tpm_sha1_final(sha1, dgt.digest);
244   return memcmp(dgt.digest, digest.digest, sizeof(TPM_DIGEST));
245 }
246 
247 /* Encryption and decryption of the TPM_DAA_SENSITIVE structure */
encrypt_daa(BYTE * iv,UINT32 iv_size,TPM_DAA_SENSITIVE * sensitive,BYTE ** enc,UINT32 * enc_size)248 static int encrypt_daa(BYTE *iv, UINT32 iv_size, TPM_DAA_SENSITIVE *sensitive,
249                        BYTE **enc, UINT32 *enc_size)
250 {
251   UINT32 len;
252   BYTE *ptr;
253   tpm_rc4_ctx_t rc4_ctx;
254   BYTE key[TPM_SYM_KEY_SIZE + iv_size];
255 
256   /* marshal sensitive */
257   *enc_size = len = sizeof_TPM_DAA_SENSITIVE((*sensitive));
258   *enc = ptr = tpm_malloc(len);
259   if (*enc == NULL)
260     return -1;
261   if (tpm_marshal_TPM_DAA_SENSITIVE(&ptr, &len, sensitive)) {
262     tpm_free(*enc);
263     return -1;
264   }
265 
266   /* encrypt sensitive */
267   memcpy(key, tpmData.permanent.data.daaKey, TPM_SYM_KEY_SIZE);
268   memcpy(&key[TPM_SYM_KEY_SIZE], iv, iv_size);
269   tpm_rc4_init(&rc4_ctx, key, sizeof(key));
270   tpm_rc4_crypt(&rc4_ctx, *enc, *enc, *enc_size);
271 
272   return 0;
273 }
274 
decrypt_daa(BYTE * iv,UINT32 iv_size,BYTE * enc,UINT32 enc_size,TPM_DAA_SENSITIVE * sensitive,BYTE ** buf)275 static int decrypt_daa(BYTE *iv, UINT32 iv_size, BYTE *enc, UINT32 enc_size,
276                        TPM_DAA_SENSITIVE *sensitive, BYTE **buf)
277 {
278   UINT32 len;
279   BYTE *ptr;
280   tpm_rc4_ctx_t rc4_ctx;
281   BYTE key[TPM_SYM_KEY_SIZE + iv_size];
282 
283   /* decrypt sensitive */
284   len = enc_size, *buf = ptr = tpm_malloc(len);
285   if (ptr == NULL)
286     return -1;
287   memcpy(key, tpmData.permanent.data.daaKey, TPM_SYM_KEY_SIZE);
288   memcpy(&key[TPM_SYM_KEY_SIZE], iv, iv_size);
289   tpm_rc4_init(&rc4_ctx, key, sizeof(key));
290   tpm_rc4_crypt(&rc4_ctx, enc, ptr, enc_size);
291 
292   /* unmarshal sensitive */
293   if (tpm_unmarshal_TPM_DAA_SENSITIVE(&ptr, &len, sensitive)) {
294     tpm_free(*buf);
295     return -1;
296   }
297 
298   return 0;
299 }
300 
301 /* Computation of the HMAC which protects the integrity of the TPM_DAA_BLOB */
compute_daa_digest(TPM_DAA_BLOB * daaBlob,TPM_DIGEST * digest)302 static int compute_daa_digest(TPM_DAA_BLOB *daaBlob, TPM_DIGEST *digest)
303 {
304   BYTE *buf, *ptr;
305   UINT32 len;
306   tpm_hmac_ctx_t hmac_ctx;
307 
308   len = sizeof_TPM_DAA_BLOB((*daaBlob));
309   buf = ptr = tpm_malloc(len);
310   if (buf == NULL)
311     return -1;
312   if (tpm_marshal_TPM_DAA_BLOB(&ptr, &len, daaBlob)) {
313     tpm_free(buf);
314     return -1;
315   }
316   memset(&buf[22], 0, sizeof(TPM_DIGEST));
317   tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.daaProof.nonce,
318     sizeof(tpmData.permanent.data.daaProof.nonce));
319   tpm_hmac_update(&hmac_ctx, buf, sizeof_TPM_DAA_BLOB((*daaBlob)));
320   tpm_hmac_final(&hmac_ctx, digest->digest);
321   tpm_free(buf);
322   return 0;
323 }
324 
325 /*
326  * DAA commands ([TPM_Part3], Section 26)
327  * Operations that are necessary to setup a TPM for DAA, execute the
328  * JOIN process, and execute the SIGN process.
329  */
330 
331 #define SCRATCH_SIZE 256
332 
TPM_DAA_Join(TPM_HANDLE handle,BYTE stage,UINT32 inputSize0,BYTE * inputData0,UINT32 inputSize1,BYTE * inputData1,TPM_AUTH * auth1,TPM_COMMAND_CODE * ordinal,UINT32 * outputSize,BYTE ** outputData)333 TPM_RESULT TPM_DAA_Join(TPM_HANDLE handle, BYTE stage, UINT32 inputSize0,
334                         BYTE *inputData0, UINT32 inputSize1,
335                         BYTE *inputData1, TPM_AUTH *auth1,
336                         TPM_COMMAND_CODE *ordinal, UINT32 *outputSize,
337                         BYTE **outputData)
338 {
339   BYTE scratch[SCRATCH_SIZE];
340   TPM_DAA_SESSION_DATA *session = NULL;
341 
342   TPM_RESULT res;
343   UINT32 cnt, len;
344   tpm_sha1_ctx_t sha1;
345   tpm_rsa_public_key_t key;
346   BYTE *signedData = NULL, *signatureValue = NULL, *DAA_generic_gamma = NULL,
347     *DAA_generic_R0 = NULL, *DAA_generic_R1 = NULL, *DAA_generic_n = NULL,
348     *DAA_generic_S0 = NULL, *DAA_generic_S1 = NULL, *ptr;
349   tpm_bn_t X, Y, Z, n, f, q, f0, f1, w1, w, gamma, r0, r1, r2, r3, r, s0, s1,
350     s12, s2, s3, E, E1, u2, u3, v0, v10, v1, tmp;
351   size_t size;
352   BYTE mgf1_seed[2 + sizeof(TPM_DIGEST)];
353   TPM_DAA_BLOB blob;
354   TPM_DAA_SENSITIVE sensitive;
355 
356   info("TPM_DAA_Join()");
357   debug("handle = %.8x, stage = %d", handle, stage);
358   debug("stany.data.currentDAA = %.8x", tpmData.stany.data.currentDAA);
359 
360   /* Initalize internal scratch pad */
361   memset(scratch, 0, SCRATCH_SIZE);
362 
363   /* Verify authorization */
364   res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
365   if (res != TPM_SUCCESS) return res;
366 
367   /* Verify and initalize the session, for all stages greater than zero. */
368   if (stage > 0) {
369     if ((HANDLE_TO_INDEX(handle) >= TPM_MAX_SESSIONS_DAA) ||
370       (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].type !=
371         TPM_ST_DAA) ||
372       (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].handle !=
373       handle)) {
374         /* Probe, whether the handle from stany.data.currentDAA is valid. */
375         handle = tpmData.stany.data.currentDAA;
376         if ((HANDLE_TO_INDEX(handle) >= TPM_MAX_SESSIONS_DAA) ||
377           (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].type !=
378             TPM_ST_DAA) ||
379           (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].handle !=
380             handle))
381               return TPM_BAD_HANDLE;
382     }
383     session = &tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)];
384   }
385 
386   /* TPM_DAA_JOIN [TPM_Part3], Section 26.1, Rev. 85 */
387   switch (stage) {
388     case 0:
389     {
390       /* Determine that sufficient resources are available to perform a
391        * DAA_Join. Assign session handle for this DAA_Join. */
392       handle = tpm_get_free_daa_session();
393       if (handle == TPM_INVALID_HANDLE)
394         return TPM_RESOURCES;
395       session = &tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)];
396       /* Set all fields in DAA_issuerSettings = NULL */
397       memset(&session->DAA_issuerSettings, 0, sizeof(TPM_DAA_ISSUER));
398       session->DAA_issuerSettings.tag = TPM_TAG_DAA_ISSUER;
399       /* Set all fields in DAA_tpmSpecific = NULL */
400       memset(&session->DAA_tpmSpecific, 0, sizeof(TPM_DAA_TPM));
401       session->DAA_tpmSpecific.tag = TPM_TAG_DAA_TPM;
402       /* Set all fields in DAA_session = NULL */
403       memset(&session->DAA_session, 0, sizeof(TPM_DAA_CONTEXT));
404       session->DAA_session.tag = TPM_TAG_DAA_CONTEXT;
405       /* Set all fields in DAA_joinSession = NULL */
406       memset(&session->DAA_joinSession, 0, sizeof(TPM_DAA_JOINDATA));
407       /* Verify that sizeOf(inputData0) == sizeOf(DAA_tpmSpecific->DAA_count)
408        * and return error TPM_DAA_INPUT_DATA0 on mismatch */
409       if (inputSize0 != sizeof(session->DAA_tpmSpecific.DAA_count)) {
410         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
411         return TPM_DAA_INPUT_DATA0;
412       }
413       /* Verify that inputData0 > 0, and return TPM_DAA_INPUT_DATA0 on
414        * mismatch */
415       ptr = inputData0, len = inputSize0;
416       if (tpm_unmarshal_UINT32(&ptr, &len, &cnt) || (len != 0)) {
417           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
418           return TPM_DAA_INPUT_DATA0;
419       }
420       if (cnt <= 0) {
421         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
422         return TPM_DAA_INPUT_DATA0;
423       }
424       /* Set DAA_tpmSpecific->DAA_count = inputData0 */
425       debug("TPM_DAA_Join() -- set DAA_count := %d", cnt);
426       session->DAA_tpmSpecific.DAA_count = cnt;
427       /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific ||
428        * DAA_joinSession) */
429       tpm_daa_update_digestContext(session, &sha1);
430       /* Set DAA_session->DAA_stage = 1 */
431       session->DAA_session.DAA_stage = 1;
432       /* Assign session handle for DAA_Join */
433       tpmData.stany.data.currentDAA = handle;
434       debug("TPM_DAA_Join() -- set handle := %.8x", handle);
435       /* Set outputData = new session handle */
436       *outputSize = sizeof(TPM_HANDLE);
437       if ((*outputData = tpm_malloc(*outputSize)) != NULL) {
438         ptr = *outputData, len = *outputSize;
439         if (tpm_marshal_TPM_HANDLE(&ptr, &len, handle)) {
440           debug("TPM_DAA_Join(): tpm_marshal_TPM_HANDLE() failed.");
441           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
442           return TPM_FAIL;
443         }
444       } else {
445         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
446         return TPM_NOSPACE;
447       }
448       /* Return TPM_SUCCESS */
449       return TPM_SUCCESS;
450     }
451     case 1:
452     {
453       /* Verify that DAA_session->DAA_stage == 1. Return TPM_DAA_STAGE
454        * and flush handle on mismatch */
455       if (session->DAA_session.DAA_stage != 1) {
456         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
457         return TPM_DAA_STAGE;
458       }
459       /* Verify that DAA_session->DAA_digestContext ==
460        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return
461        * TPM_DAA_TPM_SETTINGS on mismatch */
462       if (tpm_daa_verify_digestContext(session, &sha1)) {
463         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
464         return TPM_DAA_TPM_SETTINGS;
465       }
466       /* Verify that sizeOf(inputData0) == DAA_SIZE_issuerModulus and
467        * return error TPM_DAA_INPUT_DATA0 on mismatch */
468       if (inputSize0 != DAA_SIZE_issuerModulus) {
469         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
470         return TPM_DAA_INPUT_DATA0;
471       }
472       /* If DAA_session->DAA_scratch == NULL: */
473       if (!memcmp(scratch, session->DAA_session.DAA_scratch,
474         sizeof(session->DAA_session.DAA_scratch))) {
475           /* Set DAA_session->DAA_scratch = inputData0 */
476           memset(session->DAA_session.DAA_scratch, 0,
477             sizeof(session->DAA_session.DAA_scratch));
478           memcpy(session->DAA_session.DAA_scratch, inputData0, inputSize0);
479           /* Set DAA_joinSession->DAA_digest_n0 =
480            * SHA-1(DAA_session->DAA_scratch) */
481           tpm_sha1_init(&sha1);
482           tpm_sha1_update(&sha1, session->DAA_session.DAA_scratch,
483             sizeof(session->DAA_session.DAA_scratch));
484           tpm_sha1_final(&sha1, (BYTE*) &session->DAA_joinSession.DAA_digest_n0);
485           /* Set DAA_tpmSpecific->DAA_rekey = SHA-1(TPM_DAA_TPM_SEED ||
486            * DAA_joinSession->DAA_digest_n0) */
487           tpm_sha1_init(&sha1);
488           tpm_sha1_update(&sha1, (BYTE*) &tpmData.permanent.data.tpmDAASeed,
489             sizeof(tpmData.permanent.data.tpmDAASeed));
490           tpm_sha1_update(&sha1, (BYTE*) &session->DAA_joinSession.DAA_digest_n0,
491             sizeof(session->DAA_joinSession.DAA_digest_n0));
492           tpm_sha1_final(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey);
493       /* Else (If DAA_session->DAA_scratch != NULL): */
494       } else {
495         /* Set signedData = inputData0 */
496         signedData = inputData0;
497         /* Verify that sizeOf(inputData1) == DAA_SIZE_issuerModulus and
498          * return error TPM_DAA_INPUT_DATA1 on mismatch */
499         if (inputSize1 != DAA_SIZE_issuerModulus) {
500           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
501           return TPM_DAA_INPUT_DATA1;
502         }
503         /* Set signatureValue = inputData1 */
504         signatureValue = inputData1;
505         /* Use the RSA key == [DAA_session->DAA_scratch] to verify that
506          * signatureValue is a signature on signedData, and return error
507          * TPM_DAA_ISSUER_VALIDITY on mismatch */
508         if (tpm_rsa_import_public_key(&key, RSA_MSB_FIRST,
509           session->DAA_session.DAA_scratch, DAA_SIZE_issuerModulus, NULL, 0)) {
510             memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
511             return TPM_DAA_ISSUER_VALIDITY;
512         }
513         if (tpm_rsa_verify(&key, RSA_SSA_PKCS1_SHA1, signedData, inputSize0,
514           signatureValue)) {
515             memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
516             return TPM_DAA_ISSUER_VALIDITY;
517         }
518         tpm_rsa_release_public_key(&key);
519         /* Set DAA_session->DAA_scratch = signedData */
520         memset(session->DAA_session.DAA_scratch, 0,
521           sizeof(session->DAA_session.DAA_scratch));
522         memcpy(session->DAA_session.DAA_scratch, inputData0, inputSize0);
523       }
524       /* Decrement DAA_tpmSpecific->DAA_count by 1 (unity) */
525       session->DAA_tpmSpecific.DAA_count--;
526       /* If DAA_tpmSpecific->DAA_count == 0: */
527       if (session->DAA_tpmSpecific.DAA_count == 0) {
528         /* Increment DAA_Session->DAA_stage by 1 */
529         session->DAA_session.DAA_stage++;
530       }
531       /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific ||
532        * DAA_joinSession) */
533       tpm_daa_update_digestContext(session, &sha1);
534       /* Set outputData = NULL */
535       *outputSize = 0, *outputData = NULL;
536       /* Return TPM_SUCCESS */
537       return TPM_SUCCESS;
538     }
539     case 2:
540     {
541       /* Verify that DAA_session->DAA_stage == 2. Return TPM_DAA_STAGE
542        * and flush handle on mismatch */
543       if (session->DAA_session.DAA_stage != 2) {
544         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
545         return TPM_DAA_STAGE;
546       }
547       /* Verify that DAA_session->DAA_digestContext ==
548        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
549        * TPM_DAA_TPM_SETTINGS on mismatch */
550       if (tpm_daa_verify_digestContext(session, &sha1)) {
551         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
552         return TPM_DAA_TPM_SETTINGS;
553       }
554       /* Verify that sizeOf(inputData0) == sizeOf(TPM_DAA_ISSUER) and
555        * return error TPM_DAA_INPUT_DATA0 on mismatch */
556       if (inputSize0 != sizeof(TPM_DAA_ISSUER)) {
557         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
558         return TPM_DAA_INPUT_DATA0;
559       }
560       /* Set DAA_issuerSettings = inputData0. Verify that all fields in
561        * DAA_issuerSettings are present and return error
562        * TPM_DAA_INPUT_DATA0 if not. */
563       ptr = inputData0, len = inputSize0;
564       if (tpm_unmarshal_TPM_DAA_ISSUER(&ptr, &len,
565         &session->DAA_issuerSettings) || (len != 0) ||
566         !(session->DAA_issuerSettings.tag == TPM_TAG_DAA_ISSUER)) {
567           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
568           return TPM_DAA_INPUT_DATA0;
569       }
570       /* Verify that sizeOf(inputData1) == DAA_SIZE_issuerModulus and
571        * return error TPM_DAA_INPUT_DATA1 on mismatch */
572       if (inputSize1 != DAA_SIZE_issuerModulus) {
573         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
574         return TPM_DAA_INPUT_DATA1;
575       }
576       /* Set signatureValue = inputData1 */
577       signatureValue = inputData1;
578       /* Set signedData = (DAA_joinSession->DAA_digest_n0 ||
579        * DAA_issuerSettings) */
580       memcpy(scratch, &session->DAA_joinSession.DAA_digest_n0,
581         sizeof(TPM_DIGEST));
582       memcpy(scratch + sizeof(TPM_DIGEST), inputData0, inputSize0);
583       signedData = scratch;
584       /* Use the RSA key [DAA_session->DAA_scratch] to verify that
585        * signatureValue is a signature on signedData, and return error
586        * TPM_DAA_ISSUER_VALIDITY on mismatch */
587       if (tpm_rsa_import_public_key(&key, RSA_MSB_FIRST,
588         session->DAA_session.DAA_scratch, DAA_SIZE_issuerModulus, NULL, 0)) {
589           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
590           return TPM_DAA_ISSUER_VALIDITY;
591       }
592       if (tpm_rsa_verify(&key, RSA_SSA_PKCS1_SHA1, signedData,
593         sizeof(TPM_DIGEST) + inputSize0, signatureValue)) {
594           tpm_rsa_release_public_key(&key);
595           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
596           return TPM_DAA_ISSUER_VALIDITY;
597       }
598       tpm_rsa_release_public_key(&key);
599       /* Set DAA_tpmSpecific->DAA_digestIssuer == SHA-1(DAA_issuerSettings) */
600       tpm_daa_update_digestIssuer(session, &sha1);
601       /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific ||
602        * DAA_joinSession) */
603       tpm_daa_update_digestContext(session, &sha1);
604       /* Set DAA_session->DAA_scratch = NULL */
605       memset(session->DAA_session.DAA_scratch, 0,
606         sizeof(session->DAA_session.DAA_scratch));
607       /* Set outputData = NULL */
608       *outputSize = 0;
609       *outputData = NULL;
610       /* Increment DAA_session->DAA_stage by 1 */
611       session->DAA_session.DAA_stage++;
612       /* Return TPM_SUCCESS */
613       return TPM_SUCCESS;
614     }
615     case 3:
616     {
617       /* Verify that DAA_session->DAA_stage == 3. Return TPM_DAA_STAGE
618        * and flush handle on mismatch */
619       if (session->DAA_session.DAA_stage != 3) {
620         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
621         return TPM_DAA_STAGE;
622       }
623       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
624        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
625        * on mismatch */
626       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
627         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
628         return TPM_DAA_ISSUER_SETTINGS;
629       }
630       /* Verify that DAA_session->DAA_digestContext ==
631        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
632        * TPM_DAA_TPM_SETTINGS on mismatch */
633       if (tpm_daa_verify_digestContext(session, &sha1)) {
634         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
635         return TPM_DAA_TPM_SETTINGS;
636       }
637       /* Verify that sizeOf(inputData0) == sizeOf(DAA_tpmSpecific->DAA_count)
638        * and return error TPM_DAA_INPUT_DATA0 on mismatch */
639       if (inputSize0 != sizeof(session->DAA_tpmSpecific.DAA_count)) {
640         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
641         return TPM_DAA_INPUT_DATA0;
642       }
643       /* Set DAA_tpmSpecific->DAA_count = inputData0 */
644       ptr = inputData0, len = inputSize0;
645       if (tpm_unmarshal_UINT32(&ptr, &len,
646         &session->DAA_tpmSpecific.DAA_count) || (len != 0)) {
647           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
648           return TPM_DAA_INPUT_DATA0;
649       }
650       /* Obtain random data from the RNG and store it as
651        * DAA_joinSession->DAA_join_u0 */
652       tpm_get_random_bytes(session->DAA_joinSession.DAA_join_u0,
653         sizeof(session->DAA_joinSession.DAA_join_u0));
654       /* Obtain random data from the RNG and store it as
655        * DAA_joinSession->DAA_join_u1 */
656       tpm_get_random_bytes(session->DAA_joinSession.DAA_join_u1,
657         sizeof(session->DAA_joinSession.DAA_join_u1));
658       /* Set outputData = NULL */
659       *outputSize = 0, *outputData = NULL;
660       /* Increment DAA_session->DAA_stage by 1 */
661       session->DAA_session.DAA_stage++;
662       /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific ||
663        * DAA_joinSession) */
664       tpm_daa_update_digestContext(session, &sha1);
665       /* Return TPM_SUCCESS */
666       return TPM_SUCCESS;
667     }
668     case 4:
669     {
670       /* Verify that DAA_session->DAA_stage == 4. Return TPM_DAA_STAGE
671        * and flush handle on mismatch */
672       if (session->DAA_session.DAA_stage != 4) {
673         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
674         return TPM_DAA_STAGE;
675       }
676       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
677        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
678        * on mismatch */
679       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
680         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
681         return TPM_DAA_ISSUER_SETTINGS;
682       }
683       /* Verify that DAA_session->DAA_digestContext ==
684        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
685        * TPM_DAA_TPM_SETTINGS on mismatch */
686       if (tpm_daa_verify_digestContext(session, &sha1)) {
687         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
688         return TPM_DAA_TPM_SETTINGS;
689       }
690       /* Set DAA_generic_R0 = inputData0 */
691       DAA_generic_R0 = inputData0;
692       /* Verify that SHA-1(DAA_generic_R0) ==
693        * DAA_issuerSettings->DAA_digest_R0 and return error
694        * TPM_DAA_INPUT_DATA0 on mismatch */
695       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_R0,
696         DAA_generic_R0, inputSize0, &sha1)) {
697           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
698           return TPM_DAA_INPUT_DATA0;
699       }
700       /* Set DAA_generic_n = inputData1 */
701       DAA_generic_n = inputData1;
702       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
703        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
704       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
705         DAA_generic_n, inputSize1, &sha1)) {
706           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
707           return TPM_DAA_INPUT_DATA1;
708       }
709       /* Set X = DAA_generic_R0 */
710       tpm_bn_init(X);
711       tpm_bn_import(X, inputSize0, 1, DAA_generic_R0);
712       /* Set n = DAA_generic_n */
713       tpm_bn_init(n);
714       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
715       /* Set f = SHA1(DAA_tpmSpecific->DAA_rekey ||
716        * DAA_tpmSpecific->DAA_count || 0 ) ||
717        * SHA1(DAA_tpmSpecific->DAA_rekey || DAA_tpmSpecific->DAA_count ||
718        * 1 ) mod DAA_issuerSettings->DAA_generic_q */
719       tpm_sha1_init(&sha1);
720       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
721           sizeof(session->DAA_tpmSpecific.DAA_rekey));
722       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
723           sizeof(session->DAA_tpmSpecific.DAA_count));
724       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
725       tpm_sha1_final(&sha1, scratch);
726       tpm_sha1_init(&sha1);
727       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
728           sizeof(session->DAA_tpmSpecific.DAA_rekey));
729       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
730           sizeof(session->DAA_tpmSpecific.DAA_count));
731       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
732       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
733       tpm_bn_init(f), tpm_bn_init(q);
734       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
735       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
736         1, session->DAA_issuerSettings.DAA_generic_q);
737       tpm_bn_mod(f, f, q);
738       /* Set f0  = f mod 2^DAA_power0 (erase all but the lowest DAA_power0
739        * bits of f) */
740       tpm_bn_init(f0), tpm_bn_init(tmp);
741       tpm_bn_ui_pow_ui(tmp, 2, DAA_power0);
742       tpm_bn_mod(f0, f, tmp);
743       /* Set DAA_session->DAA_scratch = (X^f0) mod n */
744       memset(session->DAA_session.DAA_scratch, 0,
745         sizeof(session->DAA_session.DAA_scratch));
746       tpm_bn_powm(tmp, X, f0, n);
747       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
748       tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(f0), tpm_bn_clear(tmp);
749       tpm_bn_clear(X), tpm_bn_clear(n);
750       /* Set outputData = NULL */
751       *outputSize = 0, *outputData = NULL;
752       /* Increment DAA_session->DAA_stage by 1 */
753       session->DAA_session.DAA_stage++;
754       /* Return TPM_SUCCESS */
755       return TPM_SUCCESS;
756     }
757     case 5:
758     {
759       /* Verify that DAA_session->DAA_stage == 5. Return TPM_DAA_STAGE
760        * and flush handle on mismatch */
761       if (session->DAA_session.DAA_stage != 5) {
762         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
763         return TPM_DAA_STAGE;
764       }
765       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
766        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
767        * on mismatch */
768       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
769         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
770         return TPM_DAA_ISSUER_SETTINGS;
771       }
772       /* Verify that DAA_session->DAA_digestContext ==
773        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
774        * TPM_DAA_TPM_SETTINGS on mismatch */
775       if (tpm_daa_verify_digestContext(session, &sha1)) {
776         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
777         return TPM_DAA_TPM_SETTINGS;
778       }
779       /* Set DAA_generic_R1 = inputData0 */
780       DAA_generic_R1 = inputData0;
781       /* Verify that SHA-1(DAA_generic_R1) ==
782        * DAA_issuerSettings->DAA_digest_R1 and return error
783        * TPM_DAA_INPUT_DATA0 on mismatch */
784       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_R1,
785         DAA_generic_R1, inputSize0, &sha1)) {
786           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
787           return TPM_DAA_INPUT_DATA0;
788       }
789       /* Set DAA_generic_n = inputData1 */
790       DAA_generic_n = inputData1;
791       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
792        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
793       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
794         DAA_generic_n, inputSize1, &sha1)) {
795           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
796           return TPM_DAA_INPUT_DATA1;
797       }
798       /* Set X = DAA_generic_R1 */
799       tpm_bn_init(X);
800       tpm_bn_import(X, inputSize0, 1, DAA_generic_R1);
801       /* Set n = DAA_generic_n */
802       tpm_bn_init(n);
803       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
804       /* Set f = SHA1(DAA_tpmSpecific->DAA_rekey ||
805        * DAA_tpmSpecific->DAA_count || 0 ) ||
806        * SHA1(DAA_tpmSpecific->DAA_rekey || DAA_tpmSpecific->DAA_count ||
807        * 1 ) mod DAA_issuerSettings->DAA_generic_q */
808       tpm_sha1_init(&sha1);
809       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
810           sizeof(session->DAA_tpmSpecific.DAA_rekey));
811       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
812           sizeof(session->DAA_tpmSpecific.DAA_count));
813       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
814       tpm_sha1_final(&sha1, scratch);
815       tpm_sha1_init(&sha1);
816       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
817           sizeof(session->DAA_tpmSpecific.DAA_rekey));
818       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
819           sizeof(session->DAA_tpmSpecific.DAA_count));
820       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
821       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
822       tpm_bn_init(f), tpm_bn_init(q);
823       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
824       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
825         1, session->DAA_issuerSettings.DAA_generic_q);
826       tpm_bn_mod(f, f, q);
827       /* Shift f right by DAA_power0 bits (discard the lowest DAA_power0
828        * bits) and label the result f1 */
829       tpm_bn_init(f1);
830       tpm_bn_fdiv_q_2exp(f1, f, DAA_power0);
831       /* Set Z = DAA_session->DAA_scratch */
832       tpm_bn_init(Z);
833       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
834         session->DAA_session.DAA_scratch);
835       /* Set DAA_session->DAA_scratch = Z*(X^f1) mod n */
836       memset(session->DAA_session.DAA_scratch, 0,
837         sizeof(session->DAA_session.DAA_scratch));
838       tpm_bn_init(tmp);
839       tpm_bn_powm(tmp, X, f1, n);
840       tpm_bn_mul(tmp, tmp, Z);
841       tpm_bn_mod(tmp, tmp, n);
842       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
843       tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(f1), tpm_bn_clear(tmp);
844       tpm_bn_clear(X), tpm_bn_clear(n), tpm_bn_clear(Z);
845       /* Set outputData = NULL */
846       *outputSize = 0, *outputData = NULL;
847       /* Increment DAA_session->DAA_stage by 1 */
848       session->DAA_session.DAA_stage++;
849       /* Return TPM_SUCCESS */
850       return TPM_SUCCESS;
851     }
852     case 6:
853     {
854       /* Verify that DAA_session->DAA_stage == 6. Return TPM_DAA_STAGE
855        * and flush handle on mismatch */
856       if (session->DAA_session.DAA_stage != 6) {
857         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
858         return TPM_DAA_STAGE;
859       }
860       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
861        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
862        * on mismatch */
863       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
864         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
865         return TPM_DAA_ISSUER_SETTINGS;
866       }
867       /* Verify that DAA_session->DAA_digestContext ==
868        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
869        * TPM_DAA_TPM_SETTINGS on mismatch */
870       if (tpm_daa_verify_digestContext(session, &sha1)) {
871         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
872         return TPM_DAA_TPM_SETTINGS;
873       }
874       /* Set DAA_generic_S0 = inputData0 */
875       DAA_generic_S0 = inputData0;
876       /* Verify that SHA-1(DAA_generic_S0) ==
877        * DAA_issuerSettings->DAA_digest_S0 and return error
878        * TPM_DAA_INPUT_DATA0 on mismatch */
879       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_S0,
880         DAA_generic_S0, inputSize0, &sha1)) {
881           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
882           return TPM_DAA_INPUT_DATA0;
883       }
884       /* Set DAA_generic_n = inputData1 */
885       DAA_generic_n = inputData1;
886       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
887        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
888       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
889         DAA_generic_n, inputSize1, &sha1)) {
890           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
891           return TPM_DAA_INPUT_DATA1;
892       }
893       /* Set X = DAA_generic_S0 */
894       tpm_bn_init(X);
895       tpm_bn_import(X, inputSize0, 1, DAA_generic_S0);
896       /* Set n = DAA_generic_n */
897       tpm_bn_init(n);
898       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
899       /* Set Z = DAA_session->DAA_scratch */
900       tpm_bn_init(Z);
901       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
902         session->DAA_session.DAA_scratch);
903       /* Set Y = DAA_joinSession->DAA_join_u0 */
904       tpm_bn_init(Y);
905       tpm_bn_import(Y, sizeof(session->DAA_joinSession.DAA_join_u0), 1,
906         session->DAA_joinSession.DAA_join_u0);
907       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
908       memset(session->DAA_session.DAA_scratch, 0,
909         sizeof(session->DAA_session.DAA_scratch));
910       tpm_bn_init(tmp);
911       tpm_bn_powm(tmp, X, Y, n);
912       tpm_bn_mul(tmp, tmp, Z);
913       tpm_bn_mod(tmp, tmp, n);
914       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
915       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
916       /* Set outputData = NULL */
917       *outputSize = 0, *outputData = NULL;
918       /* Increment DAA_session->DAA_stage by 1 */
919       session->DAA_session.DAA_stage++;
920       /* Return TPM_SUCCESS */
921       return TPM_SUCCESS;
922     }
923     case 7:
924     {
925       /* Verify that DAA_session->DAA_stage == 7. Return TPM_DAA_STAGE
926        * and flush handle on mismatch */
927       if (session->DAA_session.DAA_stage != 7) {
928         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
929         return TPM_DAA_STAGE;
930       }
931       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
932        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
933        * on mismatch */
934       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
935         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
936         return TPM_DAA_ISSUER_SETTINGS;
937       }
938       /* Verify that DAA_session->DAA_digestContext ==
939        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
940        * TPM_DAA_TPM_SETTINGS on mismatch */
941       if (tpm_daa_verify_digestContext(session, &sha1)) {
942         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
943         return TPM_DAA_TPM_SETTINGS;
944       }
945       /* Set DAA_generic_S1 = inputData0 */
946       DAA_generic_S1 = inputData0;
947       /* Verify that SHA-1(DAA_generic_S1) ==
948        * DAA_issuerSettings->DAA_digest_S1 and return error
949        * TPM_DAA_INPUT_DATA0 on mismatch */
950       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_S1,
951         DAA_generic_S1, inputSize0, &sha1)) {
952           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
953           return TPM_DAA_INPUT_DATA0;
954       }
955       /* Set DAA_generic_n = inputData1 */
956       DAA_generic_n = inputData1;
957       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
958        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
959       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
960         DAA_generic_n, inputSize1, &sha1)) {
961           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
962           return TPM_DAA_INPUT_DATA1;
963       }
964       /* Set X = DAA_generic_S1 */
965       tpm_bn_init(X);
966       tpm_bn_import(X, inputSize0, 1, DAA_generic_S1);
967       /* Set n = DAA_generic_n */
968       tpm_bn_init(n);
969       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
970       /* Set Y = DAA_joinSession->DAA_join_u1 */
971       tpm_bn_init(Y);
972       tpm_bn_import(Y, sizeof(session->DAA_joinSession.DAA_join_u1), 1,
973         session->DAA_joinSession.DAA_join_u1);
974       /* Set Z = DAA_session->DAA_scratch */
975       tpm_bn_init(Z);
976       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
977         session->DAA_session.DAA_scratch);
978       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
979       memset(session->DAA_session.DAA_scratch, 0,
980         sizeof(session->DAA_session.DAA_scratch));
981       tpm_bn_init(tmp);
982       tpm_bn_powm(tmp, X, Y, n);
983       tpm_bn_mul(tmp, tmp, Z);
984       tpm_bn_mod(tmp, tmp, n);
985       tpm_bn_export(session->DAA_session.DAA_scratch, &size, 1, tmp);
986       memset(session->DAA_session.DAA_scratch, 0,
987         sizeof(session->DAA_session.DAA_scratch));
988       tpm_bn_export(session->DAA_session.DAA_scratch +
989         (sizeof(session->DAA_session.DAA_scratch) - size),
990         &size, 1, tmp);
991       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
992       /* Set DAA_session->DAA_digest to the SHA-1(DAA_session->DAA_scratch ||
993        * DAA_tpmSpecific->DAA_count || DAA_joinSession->DAA_digest_n0) */
994       tpm_sha1_init(&sha1);
995       tpm_sha1_update(&sha1, session->DAA_session.DAA_scratch,
996         sizeof(session->DAA_session.DAA_scratch));
997       ptr = scratch, len = sizeof(scratch);
998       if (tpm_marshal_UINT32(&ptr, &len, session->DAA_tpmSpecific.DAA_count)) {
999         debug("TPM_DAA_Join(): tpm_marshal_UINT32() failed.");
1000         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1001         return TPM_FAIL;
1002       }
1003       tpm_sha1_update(&sha1, scratch, sizeof(UINT32));
1004       tpm_sha1_update(&sha1, session->DAA_joinSession.DAA_digest_n0.digest,
1005         sizeof(session->DAA_joinSession.DAA_digest_n0.digest));
1006       tpm_sha1_final(&sha1, session->DAA_session.DAA_digest.digest);
1007       /* Set outputData = DAA_session->DAA_scratch */
1008       *outputSize = sizeof(session->DAA_session.DAA_scratch);
1009       if ((*outputData = tpm_malloc(*outputSize)) != NULL) {
1010         memcpy(*outputData, session->DAA_session.DAA_scratch, *outputSize);
1011       } else {
1012         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1013         return TPM_NOSPACE;
1014       }
1015       /* Set DAA_session->DAA_scratch = NULL */
1016       memset(session->DAA_session.DAA_scratch, 0,
1017         sizeof(session->DAA_session.DAA_scratch));
1018       /* Increment DAA_session->DAA_stage by 1 */
1019       session->DAA_session.DAA_stage++;
1020       /* Return TPM_SUCCESS */
1021       return TPM_SUCCESS;
1022     }
1023     case 8:
1024     {
1025       /* Verify that DAA_session->DAA_stage == 8. Return TPM_DAA_STAGE
1026        * and flush handle on mismatch */
1027       if (session->DAA_session.DAA_stage != 8) {
1028         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1029         return TPM_DAA_STAGE;
1030       }
1031       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1032        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1033        * on mismatch */
1034       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1035         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1036         return TPM_DAA_ISSUER_SETTINGS;
1037       }
1038       /* Verify that DAA_session->DAA_digestContext ==
1039        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1040        * TPM_DAA_TPM_SETTINGS on mismatch */
1041       if (tpm_daa_verify_digestContext(session, &sha1)) {
1042         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1043         return TPM_DAA_TPM_SETTINGS;
1044       }
1045       /* Verify inputSize0 == DAA_SIZE_NE and return error
1046        * TPM_DAA_INPUT_DATA0 on mismatch */
1047       if (inputSize0 != DAA_SIZE_NE) {
1048         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1049         return TPM_DAA_INPUT_DATA0;
1050       }
1051       /* Set NE = decrypt(inputData0, privEK) */
1052       memset(scratch, 0, sizeof(scratch));
1053       if (tpm_rsa_decrypt(&tpmData.permanent.data.endorsementKey,
1054         RSA_ES_OAEP_SHA1, inputData0, inputSize0, scratch, &size)) {
1055           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1056           return TPM_DECRYPT_ERROR;
1057       }
1058       /* Set outputData = SHA-1(DAA_session->DAA_digest || NE) */
1059       *outputSize = SHA1_DIGEST_LENGTH;
1060       if ((*outputData = tpm_malloc(*outputSize)) == NULL) {
1061         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1062         return TPM_NOSPACE;
1063       }
1064       tpm_sha1_init(&sha1);
1065       tpm_sha1_update(&sha1, session->DAA_session.DAA_digest.digest,
1066         sizeof(session->DAA_session.DAA_digest.digest));
1067       tpm_sha1_update(&sha1, scratch, size);
1068       tpm_sha1_final(&sha1, *outputData);
1069       /* Set DAA_session->DAA_digest = NULL */
1070       memset(&session->DAA_session.DAA_digest, 0,
1071         sizeof(session->DAA_session.DAA_digest));
1072       /* Increment DAA_session->DAA_stage by 1 */
1073       session->DAA_session.DAA_stage++;
1074       /* Return TPM_SUCCESS */
1075       return TPM_SUCCESS;
1076     }
1077     case 9:
1078     {
1079       /* Verify that DAA_session->DAA_stage == 9. Return TPM_DAA_STAGE
1080        * and flush handle on mismatch */
1081       if (session->DAA_session.DAA_stage != 9) {
1082         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1083         return TPM_DAA_STAGE;
1084       }
1085       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1086        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1087        * on mismatch */
1088       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1089         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1090         return TPM_DAA_ISSUER_SETTINGS;
1091       }
1092       /* Verify that DAA_session->DAA_digestContext ==
1093        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1094        * TPM_DAA_TPM_SETTINGS on mismatch */
1095       if (tpm_daa_verify_digestContext(session, &sha1)) {
1096         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1097         return TPM_DAA_TPM_SETTINGS;
1098       }
1099       /* Set DAA_generic_R0 = inputData0 */
1100       DAA_generic_R0 = inputData0;
1101       /* Verify that SHA-1(DAA_generic_R0) ==
1102        * DAA_issuerSettings->DAA_digest_R0 and return error
1103        * TPM_DAA_INPUT_DATA0 on mismatch */
1104       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_R0,
1105         DAA_generic_R0, inputSize0, &sha1)) {
1106           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1107           return TPM_DAA_INPUT_DATA0;
1108       }
1109       /* Set DAA_generic_n = inputData1 */
1110       DAA_generic_n = inputData1;
1111       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
1112        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
1113       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
1114         DAA_generic_n, inputSize1, &sha1)) {
1115           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1116           return TPM_DAA_INPUT_DATA1;
1117       }
1118       /* Obtain random data from the RNG and store it as
1119        * DAA_session->DAA_contextSeed */
1120       tpm_get_random_bytes(session->DAA_session.DAA_contextSeed.nonce,
1121         sizeof(TPM_NONCE));
1122       /* Obtain DAA_SIZE_r0 bits from MGF1("r0",
1123        * DAA_session->DAA_contextSeed), and label them Y */
1124       memset(scratch, 0, sizeof(scratch));
1125       memcpy(mgf1_seed, "r0", 2);
1126       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1127         sizeof(TPM_NONCE));
1128       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r0);
1129       tpm_bn_init(Y);
1130       tpm_bn_import(Y, DAA_SIZE_r0, 1, scratch);
1131       /* Set X = DAA_generic_R0 */
1132       tpm_bn_init(X);
1133       tpm_bn_import(X, inputSize0, 1, DAA_generic_R0);
1134       /* Set n = DAA_generic_n */
1135       tpm_bn_init(n);
1136       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
1137       /* Set DAA_session->DAA_scratch = (X^Y) mod n */
1138       memset(session->DAA_session.DAA_scratch, 0,
1139         sizeof(session->DAA_session.DAA_scratch));
1140       tpm_bn_init(tmp);
1141       tpm_bn_powm(tmp, X, Y, n);
1142       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
1143       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(n), tpm_bn_clear(tmp);
1144       /* Set outputData = NULL */
1145       *outputSize = 0, *outputData = NULL;
1146       /* Increment DAA_session->DAA_stage by 1 */
1147       session->DAA_session.DAA_stage++;
1148       /* Return TPM_SUCCESS */
1149       return TPM_SUCCESS;
1150     }
1151     case 10:
1152     {
1153       /* Verify that DAA_session->DAA_stage == 10. Return TPM_DAA_STAGE
1154        * and flush handle on mismatch */
1155       if (session->DAA_session.DAA_stage != 10) {
1156         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1157         return TPM_DAA_STAGE;
1158       }
1159       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1160        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1161        * on mismatch */
1162       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1163         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1164         return TPM_DAA_ISSUER_SETTINGS;
1165       }
1166       /* Verify that DAA_session->DAA_digestContext ==
1167        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1168        * TPM_DAA_TPM_SETTINGS on mismatch */
1169       if (tpm_daa_verify_digestContext(session, &sha1)) {
1170         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1171         return TPM_DAA_TPM_SETTINGS;
1172       }
1173       /* Set DAA_generic_R1 = inputData0 */
1174       DAA_generic_R1 = inputData0;
1175       /* Verify that SHA-1(DAA_generic_R1) ==
1176        * DAA_issuerSettings->DAA_digest_R1 and return error
1177        * TPM_DAA_INPUT_DATA0 on mismatch */
1178       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_R1,
1179         DAA_generic_R1, inputSize0, &sha1)) {
1180           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1181           return TPM_DAA_INPUT_DATA0;
1182       }
1183       /* Set DAA_generic_n = inputData1 */
1184       DAA_generic_n = inputData1;
1185       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
1186        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
1187       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
1188         DAA_generic_n, inputSize1, &sha1)) {
1189           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1190           return TPM_DAA_INPUT_DATA1;
1191       }
1192       /* Obtain DAA_SIZE_r1 bits from MGF1("r1",
1193        * DAA_session->DAA_contextSeed), and label them Y */
1194       memset(scratch, 0, sizeof(scratch));
1195       memcpy(mgf1_seed, "r1", 2);
1196       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1197         sizeof(TPM_NONCE));
1198       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r1);
1199       tpm_bn_init(Y);
1200       tpm_bn_import(Y, DAA_SIZE_r1, 1, scratch);
1201       /* Set X = DAA_generic_R1 */
1202       tpm_bn_init(X);
1203       tpm_bn_import(X, inputSize0, 1, DAA_generic_R1);
1204       /* Set n = DAA_generic_n */
1205       tpm_bn_init(n);
1206       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
1207       /* Set Z = DAA_session->DAA_scratch */
1208       tpm_bn_init(Z);
1209       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
1210         session->DAA_session.DAA_scratch);
1211       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
1212       memset(session->DAA_session.DAA_scratch, 0,
1213         sizeof(session->DAA_session.DAA_scratch));
1214       tpm_bn_init(tmp);
1215       tpm_bn_powm(tmp, X, Y, n);
1216       tpm_bn_mul(tmp, tmp, Z);
1217       tpm_bn_mod(tmp, tmp, n);
1218       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
1219       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
1220       /* Set outputData = NULL */
1221       *outputSize = 0, *outputData = NULL;
1222       /* Increment DAA_session->DAA_stage by 1 */
1223       session->DAA_session.DAA_stage++;
1224       /* Return TPM_SUCCESS */
1225       return TPM_SUCCESS;
1226     }
1227     case 11:
1228     {
1229       /* Verify that DAA_session->DAA_stage == 11. Return TPM_DAA_STAGE
1230        * and flush handle on mismatch */
1231       if (session->DAA_session.DAA_stage != 11) {
1232         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1233         return TPM_DAA_STAGE;
1234       }
1235       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1236        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1237        * on mismatch */
1238       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1239         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1240         return TPM_DAA_ISSUER_SETTINGS;
1241       }
1242       /* Verify that DAA_session->DAA_digestContext ==
1243        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1244        * TPM_DAA_TPM_SETTINGS on mismatch */
1245       if (tpm_daa_verify_digestContext(session, &sha1)) {
1246         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1247         return TPM_DAA_TPM_SETTINGS;
1248       }
1249       /* Set DAA_generic_S0 = inputData0 */
1250       DAA_generic_S0 = inputData0;
1251       /* Verify that SHA-1(DAA_generic_S0) ==
1252        * DAA_issuerSettings->DAA_digest_S0 and return error
1253        * TPM_DAA_INPUT_DATA0 on mismatch */
1254       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_S0,
1255         DAA_generic_S0, inputSize0, &sha1)) {
1256           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1257           return TPM_DAA_INPUT_DATA0;
1258       }
1259       /* Set DAA_generic_n = inputData1 */
1260       DAA_generic_n = inputData1;
1261       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
1262        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
1263       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
1264         DAA_generic_n, inputSize1, &sha1)) {
1265           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1266           return TPM_DAA_INPUT_DATA1;
1267       }
1268       /* Obtain DAA_SIZE_r2 bits from MGF1("r2",
1269        * DAA_session->DAA_contextSeed), and label them Y */
1270       memset(scratch, 0, sizeof(scratch));
1271       memcpy(mgf1_seed, "r2", 2);
1272       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1273         sizeof(TPM_NONCE));
1274       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r2);
1275       tpm_bn_init(Y);
1276       tpm_bn_import(Y, DAA_SIZE_r2, 1, scratch);
1277       /* Set X = DAA_generic_S0 */
1278       tpm_bn_init(X);
1279       tpm_bn_import(X, inputSize0, 1, DAA_generic_S0);
1280       /* Set n = DAA_generic_n */
1281       tpm_bn_init(n);
1282       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
1283       /* Set Z = DAA_session->DAA_scratch */
1284       tpm_bn_init(Z);
1285       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
1286         session->DAA_session.DAA_scratch);
1287       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
1288       memset(session->DAA_session.DAA_scratch, 0,
1289         sizeof(session->DAA_session.DAA_scratch));
1290       tpm_bn_init(tmp);
1291       tpm_bn_powm(tmp, X, Y, n);
1292       tpm_bn_mul(tmp, tmp, Z);
1293       tpm_bn_mod(tmp, tmp, n);
1294       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
1295       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
1296       /* Set outputData = NULL */
1297       *outputSize = 0, *outputData = NULL;
1298       /* Increment DAA_session->DAA_stage by 1 */
1299       session->DAA_session.DAA_stage++;
1300       /* Return TPM_SUCCESS */
1301       return TPM_SUCCESS;
1302     }
1303     case 12:
1304     {
1305       /* Verify that DAA_session->DAA_stage == 12. Return TPM_DAA_STAGE
1306        * and flush handle on mismatch */
1307       if (session->DAA_session.DAA_stage != 12) {
1308         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1309         return TPM_DAA_STAGE;
1310       }
1311       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1312        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1313        * on mismatch */
1314       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1315         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1316         return TPM_DAA_ISSUER_SETTINGS;
1317       }
1318       /* Verify that DAA_session->DAA_digestContext ==
1319        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1320        * TPM_DAA_TPM_SETTINGS on mismatch */
1321       if (tpm_daa_verify_digestContext(session, &sha1)) {
1322         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1323         return TPM_DAA_TPM_SETTINGS;
1324       }
1325       /* Set DAA_generic_S1 = inputData0 */
1326       DAA_generic_S1 = inputData0;
1327       /* Verify that SHA-1(DAA_generic_S1) ==
1328        * DAA_issuerSettings->DAA_digest_S1 and return error
1329        * TPM_DAA_INPUT_DATA0 on mismatch */
1330       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_S1,
1331         DAA_generic_S1, inputSize0, &sha1)) {
1332           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1333           return TPM_DAA_INPUT_DATA0;
1334       }
1335       /* Set DAA_generic_n = inputData1 */
1336       DAA_generic_n = inputData1;
1337       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
1338        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
1339       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
1340         DAA_generic_n, inputSize1, &sha1)) {
1341           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1342           return TPM_DAA_INPUT_DATA1;
1343       }
1344       /* Obtain DAA_SIZE_r3 bits from MGF1("r3",
1345        * DAA_session->DAA_contextSeed), and label them Y */
1346       memset(scratch, 0, sizeof(scratch));
1347       memcpy(mgf1_seed, "r3", 2);
1348       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1349         sizeof(TPM_NONCE));
1350       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r3);
1351       tpm_bn_init(Y);
1352       tpm_bn_import(Y, DAA_SIZE_r3, 1, scratch);
1353       /* Set X = DAA_generic_S1 */
1354       tpm_bn_init(X);
1355       tpm_bn_import(X, inputSize0, 1, DAA_generic_S1);
1356       /* Set n = DAA_generic_n */
1357       tpm_bn_init(n);
1358       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
1359       /* Set Z = DAA_session->DAA_scratch */
1360       tpm_bn_init(Z);
1361       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
1362         session->DAA_session.DAA_scratch);
1363       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
1364       memset(session->DAA_session.DAA_scratch, 0,
1365         sizeof(session->DAA_session.DAA_scratch));
1366       tpm_bn_init(tmp);
1367       tpm_bn_powm(tmp, X, Y, n);
1368       tpm_bn_mul(tmp, tmp, Z);
1369       tpm_bn_mod(tmp, tmp, n);
1370       tpm_bn_export(session->DAA_session.DAA_scratch, &size, 1, tmp);
1371       *outputSize = (uint32_t)size;
1372       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
1373       /* Set outputData = DAA_session->DAA_scratch */
1374       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1375         memcpy(*outputData, session->DAA_session.DAA_scratch, *outputSize);
1376       else {
1377         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1378         return TPM_NOSPACE;
1379       }
1380       /* Set DAA_session->DAA_scratch = NULL */
1381       memset(session->DAA_session.DAA_scratch, 0,
1382         sizeof(session->DAA_session.DAA_scratch));
1383       /* Increment DAA_session->DAA_stage by 1 */
1384       session->DAA_session.DAA_stage++;
1385       /* Return TPM_SUCCESS */
1386       return TPM_SUCCESS;
1387     }
1388     case 13:
1389     {
1390       /* Verify that DAA_session->DAA_stage == 13. Return TPM_DAA_STAGE
1391        * and flush handle on mismatch */
1392       if (session->DAA_session.DAA_stage != 13) {
1393         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1394         return TPM_DAA_STAGE;
1395       }
1396       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1397        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1398        * on mismatch */
1399       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1400         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1401         return TPM_DAA_ISSUER_SETTINGS;
1402       }
1403       /* Verify that DAA_session->DAA_digestContext ==
1404        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1405        * TPM_DAA_TPM_SETTINGS on mismatch */
1406       if (tpm_daa_verify_digestContext(session, &sha1)) {
1407         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1408         return TPM_DAA_TPM_SETTINGS;
1409       }
1410       /* Set DAA_generic_gamma = inputData0 */
1411       DAA_generic_gamma = inputData0;
1412       /* Verify that SHA-1(DAA_generic_gamma) ==
1413        * DAA_issuerSettings->DAA_digest_gamma and return error
1414        * TPM_DAA_INPUT_DATA0 on mismatch */
1415       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_gamma,
1416         DAA_generic_gamma, inputSize0, &sha1)) {
1417           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1418           return TPM_DAA_INPUT_DATA0;
1419       }
1420       /* Verify that inputSize1 == DAA_SIZE_w and return error
1421        * TPM_DAA_INPUT_DATA1 on mismatch */
1422       if (inputSize1 != DAA_SIZE_w) {
1423         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1424         return TPM_DAA_INPUT_DATA1;
1425       }
1426       /* Set w = inputData1 */
1427       tpm_bn_init(w);
1428       tpm_bn_import(w, inputSize1, 1, inputData1);
1429       /* Set w1 = w^(DAA_issuerSettings->DAA_generic_q) mod
1430        * (DAA_generic_gamma) */
1431       tpm_bn_init(gamma);
1432       tpm_bn_import(gamma, inputSize0, 1, DAA_generic_gamma);
1433       tpm_bn_init(q);
1434       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
1435         1, session->DAA_issuerSettings.DAA_generic_q);
1436       tpm_bn_init(w1);
1437       tpm_bn_powm(w1, w, q, gamma);
1438       /* If w1 != 1 (unity), return error TPM_DAA_WRONG_W */
1439       if (tpm_bn_cmp_ui(w1, 1)) {
1440         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1441         return TPM_DAA_WRONG_W;
1442       }
1443       /* Set DAA_session->DAA_scratch = w */
1444       memset(session->DAA_session.DAA_scratch, 0,
1445         sizeof(session->DAA_session.DAA_scratch));
1446       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, w);
1447       tpm_bn_clear(w), tpm_bn_clear(gamma), tpm_bn_clear(w1), tpm_bn_clear(q);
1448       /* Set outputData = NULL */
1449       *outputSize = 0, *outputData = NULL;
1450       /* Increment DAA_session->DAA_stage by 1 */
1451       session->DAA_session.DAA_stage++;
1452       /* Return TPM_SUCCESS */
1453       return TPM_SUCCESS;
1454     }
1455     case 14:
1456     {
1457       /* Verify that DAA_session->DAA_stage == 14. Return TPM_DAA_STAGE
1458        * and flush handle on mismatch */
1459       if (session->DAA_session.DAA_stage != 14) {
1460         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1461         return TPM_DAA_STAGE;
1462       }
1463       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1464        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1465        * on mismatch */
1466       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1467         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1468         return TPM_DAA_ISSUER_SETTINGS;
1469       }
1470       /* Verify that DAA_session->DAA_digestContext ==
1471        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1472        * TPM_DAA_TPM_SETTINGS on mismatch */
1473       if (tpm_daa_verify_digestContext(session, &sha1)) {
1474         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1475         return TPM_DAA_TPM_SETTINGS;
1476       }
1477       /* Set DAA_generic_gamma = inputData0 */
1478       DAA_generic_gamma = inputData0;
1479       /* Verify that SHA-1(DAA_generic_gamma) ==
1480        * DAA_issuerSettings->DAA_digest_gamma and return error
1481        * TPM_DAA_INPUT_DATA0 on mismatch */
1482       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_gamma,
1483         DAA_generic_gamma, inputSize0, &sha1)) {
1484           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1485           return TPM_DAA_INPUT_DATA0;
1486       }
1487       /* Set f = SHA-1(DAA_tpmSpecific->DAA_rekey ||
1488        * DAA_tpmSpecific->DAA_count || 0) || SHA-1(DAA_tpmSpecific->DAA_rekey
1489        * || DAA_tpmSpecific->DAA_count || 1) mod
1490        * DAA_issuerSettings->DAA_generic_q. */
1491       tpm_sha1_init(&sha1);
1492       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
1493           sizeof(session->DAA_tpmSpecific.DAA_rekey));
1494       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
1495           sizeof(session->DAA_tpmSpecific.DAA_count));
1496       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
1497       tpm_sha1_final(&sha1, scratch);
1498       tpm_sha1_init(&sha1);
1499       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
1500           sizeof(session->DAA_tpmSpecific.DAA_rekey));
1501       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
1502           sizeof(session->DAA_tpmSpecific.DAA_count));
1503       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
1504       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
1505       tpm_bn_init(f), tpm_bn_init(q);
1506       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
1507       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
1508         1, session->DAA_issuerSettings.DAA_generic_q);
1509       tpm_bn_mod(f, f, q);
1510       /* Set E = ((DAA_session->DAA_scratch)^f) mod (DAA_generic_gamma).*/
1511       tpm_bn_init(gamma);
1512       tpm_bn_import(gamma, inputSize0, 1, DAA_generic_gamma);
1513       tpm_bn_init(w);
1514       tpm_bn_import(w, sizeof(session->DAA_session.DAA_scratch), -1,
1515         session->DAA_session.DAA_scratch);
1516       tpm_bn_init(E);
1517       tpm_bn_powm(E, w, f, gamma);
1518       /* Set outputData = E */
1519       tpm_bn_export(scratch, &size, 1, E);
1520       *outputSize = (uint32_t)size;
1521       tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(gamma), tpm_bn_clear(w), tpm_bn_clear(E);
1522       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1523         memcpy(*outputData, scratch, *outputSize);
1524       else {
1525         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1526         return TPM_NOSPACE;
1527       }
1528       /* Increment DAA_session->DAA_stage by 1 */
1529       session->DAA_session.DAA_stage++;
1530       /* Return TPM_SUCCESS */
1531       return TPM_SUCCESS;
1532     }
1533     case 15:
1534     {
1535       /* Verify that DAA_session->DAA_stage == 15. Return TPM_DAA_STAGE
1536        * and flush handle on mismatch */
1537       if (session->DAA_session.DAA_stage != 15) {
1538         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1539         return TPM_DAA_STAGE;
1540       }
1541       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1542        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1543        * on mismatch */
1544       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1545         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1546         return TPM_DAA_ISSUER_SETTINGS;
1547       }
1548       /* Verify that DAA_session->DAA_digestContext ==
1549        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1550        * TPM_DAA_TPM_SETTINGS on mismatch */
1551       if (tpm_daa_verify_digestContext(session, &sha1)) {
1552         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1553         return TPM_DAA_TPM_SETTINGS;
1554       }
1555       /* Set DAA_generic_gamma = inputData0 */
1556       DAA_generic_gamma = inputData0;
1557       /* Verify that SHA-1(DAA_generic_gamma) ==
1558        * DAA_issuerSettings->DAA_digest_gamma and return error
1559        * TPM_DAA_INPUT_DATA0 on mismatch */
1560       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_gamma,
1561         DAA_generic_gamma, inputSize0, &sha1)) {
1562           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1563           return TPM_DAA_INPUT_DATA0;
1564       }
1565       /* Obtain DAA_SIZE_r0 bits from MGF1("r0",
1566        * DAA_session->DAA_contextSeed), and label them r0 */
1567       memset(scratch, 0, sizeof(scratch));
1568       memcpy(mgf1_seed, "r0", 2);
1569       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1570         sizeof(TPM_NONCE));
1571       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r0);
1572       tpm_bn_init(r0);
1573       tpm_bn_import(r0, DAA_SIZE_r0, 1, scratch);
1574       /* Obtain DAA_SIZE_r1 bits from MGF1("r1",
1575        * DAA_session->DAA_contextSeed), and label them r1 */
1576       memset(scratch, 0, sizeof(scratch));
1577       memcpy(mgf1_seed, "r1", 2);
1578       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1579         sizeof(TPM_NONCE));
1580       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r1);
1581       tpm_bn_init(r1);
1582       tpm_bn_import(r1, DAA_SIZE_r1, 1, scratch);
1583       /* Set r = r0 + 2^DAA_power0 * r1 mod
1584        * (DAA_issuerSettings->DAA_generic_q). */
1585       tpm_bn_init(q);
1586       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
1587         1, session->DAA_issuerSettings.DAA_generic_q);
1588       tpm_bn_init(r);
1589       tpm_bn_ui_pow_ui(r, 2, DAA_power0);
1590       tpm_bn_mul(r, r, r1);
1591       tpm_bn_mod(r, r, q);
1592       tpm_bn_add(r, r, r0);
1593       tpm_bn_mod(r, r, q);
1594       /* Set E1 = ((DAA_session->DAA_scratch)^r) mod (DAA_generic_gamma). */
1595       tpm_bn_init(gamma);
1596       tpm_bn_import(gamma, inputSize0, 1, DAA_generic_gamma);
1597       tpm_bn_init(w);
1598       tpm_bn_import(w, sizeof(session->DAA_session.DAA_scratch), -1,
1599         session->DAA_session.DAA_scratch);
1600       tpm_bn_init(E1);
1601       tpm_bn_powm(E1, w, r, gamma);
1602       /* Set DAA_session->DAA_scratch = NULL */
1603       memset(session->DAA_session.DAA_scratch, 0,
1604         sizeof(session->DAA_session.DAA_scratch));
1605       /* Set outputData = E1 */
1606       tpm_bn_export(scratch, &size, 1, E1);
1607       *outputSize = (uint32_t)size;
1608       tpm_bn_clear(r0), tpm_bn_clear(r1), tpm_bn_clear(q), tpm_bn_clear(r);
1609       tpm_bn_clear(gamma), tpm_bn_clear(w), tpm_bn_clear(E1);
1610       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1611         memcpy(*outputData, scratch, *outputSize);
1612       else {
1613         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1614         return TPM_NOSPACE;
1615       }
1616       /* Increment DAA_session->DAA_stage by 1 */
1617       session->DAA_session.DAA_stage++;
1618       /* Return TPM_SUCCESS */
1619       return TPM_SUCCESS;
1620     }
1621     case 16:
1622     {
1623       BYTE *NT = NULL;
1624 
1625       /* Verify that DAA_session->DAA_stage == 16. Return TPM_DAA_STAGE
1626        * and flush handle on mismatch */
1627       if (session->DAA_session.DAA_stage != 16) {
1628         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1629         return TPM_DAA_STAGE;
1630       }
1631       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1632        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1633        * on mismatch */
1634       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1635         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1636         return TPM_DAA_ISSUER_SETTINGS;
1637       }
1638       /* Verify that DAA_session->DAA_digestContext ==
1639        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1640        * TPM_DAA_TPM_SETTINGS on mismatch */
1641       if (tpm_daa_verify_digestContext(session, &sha1)) {
1642         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1643         return TPM_DAA_TPM_SETTINGS;
1644       }
1645       /* Verify that inputSize0 == sizeOf(TPM_DIGEST) and return error
1646        * TPM_DAA_INPUT_DATA0 on mismatch */
1647       if (inputSize0 != sizeof(TPM_DIGEST)) {
1648         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1649         return TPM_DAA_INPUT_DATA0;
1650       }
1651       /* Set DAA_session->DAA_digest = inputData0 */
1652       memcpy(session->DAA_session.DAA_digest.digest, inputData0, inputSize0);
1653       /* Obtain DAA_SIZE_NT bits from the RNG and label them NT */
1654       if ((NT = tpm_malloc(DAA_SIZE_NT)) == NULL) {
1655         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1656         return TPM_NOSPACE;
1657       }
1658       tpm_get_random_bytes(NT, DAA_SIZE_NT);
1659       /* Set DAA_session->DAA_digest to the SHA-1(DAA_session->DAA_digest ||
1660        * NT)*/
1661       tpm_sha1_init(&sha1);
1662       tpm_sha1_update(&sha1, (BYTE*) session->DAA_session.DAA_digest.digest,
1663           sizeof(session->DAA_session.DAA_digest.digest));
1664       tpm_sha1_update(&sha1, NT, DAA_SIZE_NT);
1665       tpm_sha1_final(&sha1, session->DAA_session.DAA_digest.digest);
1666       /* Set outputData = NT */
1667       *outputSize = DAA_SIZE_NT;
1668       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1669         memcpy(*outputData, NT, *outputSize);
1670       else {
1671         tpm_free(NT);
1672         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1673         return TPM_NOSPACE;
1674       }
1675       tpm_free(NT);
1676       /* Increment DAA_session->DAA_stage by 1 */
1677       session->DAA_session.DAA_stage++;
1678       /* Return TPM_SUCCESS */
1679       return TPM_SUCCESS;
1680     }
1681     case 17:
1682     {
1683       /* Verify that DAA_session->DAA_stage == 17. Return TPM_DAA_STAGE
1684        * and flush handle on mismatch */
1685       if (session->DAA_session.DAA_stage != 17) {
1686         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1687         return TPM_DAA_STAGE;
1688       }
1689       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1690        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1691        * on mismatch */
1692       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1693         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1694         return TPM_DAA_ISSUER_SETTINGS;
1695       }
1696       /* Verify that DAA_session->DAA_digestContext ==
1697        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1698        * TPM_DAA_TPM_SETTINGS on mismatch */
1699       if (tpm_daa_verify_digestContext(session, &sha1)) {
1700         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1701         return TPM_DAA_TPM_SETTINGS;
1702       }
1703       /* Obtain DAA_SIZE_r0 bits from MGF1("r0",
1704        * DAA_session->DAA_contextSeed), and label them r0 */
1705       memset(scratch, 0, sizeof(scratch));
1706       memcpy(mgf1_seed, "r0", 2);
1707       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1708         sizeof(TPM_NONCE));
1709       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r0);
1710       tpm_bn_init(r0);
1711       tpm_bn_import(r0, DAA_SIZE_r0, 1, scratch);
1712       /* Set f = SHA1(DAA_tpmSpecific->DAA_rekey ||
1713        * DAA_tpmSpecific->DAA_count || 0 ) ||
1714        * SHA1(DAA_tpmSpecific->DAA_rekey || DAA_tpmSpecific->DAA_count ||
1715        * 1 ) mod DAA_issuerSettings->DAA_generic_q */
1716       tpm_sha1_init(&sha1);
1717       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
1718           sizeof(session->DAA_tpmSpecific.DAA_rekey));
1719       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
1720           sizeof(session->DAA_tpmSpecific.DAA_count));
1721       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
1722       tpm_sha1_final(&sha1, scratch);
1723       tpm_sha1_init(&sha1);
1724       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
1725           sizeof(session->DAA_tpmSpecific.DAA_rekey));
1726       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
1727           sizeof(session->DAA_tpmSpecific.DAA_count));
1728       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
1729       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
1730       tpm_bn_init(f), tpm_bn_init(q);
1731       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
1732       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
1733         1, session->DAA_issuerSettings.DAA_generic_q);
1734       tpm_bn_mod(f, f, q);
1735       /* Set f0 = f mod 2^DAA_power0 (erase all but the lowest DAA_power0
1736        * bits of f) */
1737       tpm_bn_init(f0);
1738       tpm_bn_init(tmp);
1739       tpm_bn_ui_pow_ui(tmp, 2, DAA_power0);
1740       tpm_bn_mod(f0, f, tmp);
1741       /* Set s0 = r0 + (DAA_session->DAA_digest) * f0 in Z */
1742       tpm_bn_init(s0);
1743       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
1744         1, session->DAA_session.DAA_digest.digest);
1745       tpm_bn_mul(s0, tmp, f0);
1746       tpm_bn_add(s0, r0, s0);
1747       /* Set outputData = s0 */
1748       tpm_bn_export(scratch, &size, 1, s0);
1749       *outputSize = (uint32_t)size;
1750       tpm_bn_clear(r0), tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(f0);
1751       tpm_bn_clear(s0), tpm_bn_clear(tmp);
1752       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1753         memcpy(*outputData, scratch, *outputSize);
1754       else {
1755         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1756         return TPM_NOSPACE;
1757       }
1758       /* Increment DAA_session->DAA_stage by 1 */
1759       session->DAA_session.DAA_stage++;
1760       /* Return TPM_SUCCESS */
1761       return TPM_SUCCESS;
1762     }
1763     case 18:
1764     {
1765       /* Verify that DAA_session->DAA_stage == 18. Return TPM_DAA_STAGE
1766        * and flush handle on mismatch */
1767       if (session->DAA_session.DAA_stage != 18) {
1768         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1769         return TPM_DAA_STAGE;
1770       }
1771       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1772        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1773        * on mismatch */
1774       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1775         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1776         return TPM_DAA_ISSUER_SETTINGS;
1777       }
1778       /* Verify that DAA_session->DAA_digestContext ==
1779        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1780        * TPM_DAA_TPM_SETTINGS on mismatch */
1781       if (tpm_daa_verify_digestContext(session, &sha1)) {
1782         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1783         return TPM_DAA_TPM_SETTINGS;
1784       }
1785       /* Obtain DAA_SIZE_r1 bits from MGF1("r1",
1786        * DAA_session->DAA_contextSeed), and label them r1 */
1787       memset(scratch, 0, sizeof(scratch));
1788       memcpy(mgf1_seed, "r1", 2);
1789       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1790         sizeof(TPM_NONCE));
1791       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r1);
1792       tpm_bn_init(r1);
1793       tpm_bn_import(r1, DAA_SIZE_r1, 1, scratch);
1794       /* Set f = SHA1(DAA_tpmSpecific->DAA_rekey ||
1795        * DAA_tpmSpecific->DAA_count || 0 ) ||
1796        * SHA1(DAA_tpmSpecific->DAA_rekey || DAA_tpmSpecific->DAA_count ||
1797        * 1 ) mod DAA_issuerSettings->DAA_generic_q */
1798       tpm_sha1_init(&sha1);
1799       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
1800           sizeof(session->DAA_tpmSpecific.DAA_rekey));
1801       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
1802           sizeof(session->DAA_tpmSpecific.DAA_count));
1803       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
1804       tpm_sha1_final(&sha1, scratch);
1805       tpm_sha1_init(&sha1);
1806       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
1807           sizeof(session->DAA_tpmSpecific.DAA_rekey));
1808       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
1809           sizeof(session->DAA_tpmSpecific.DAA_count));
1810       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
1811       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
1812       tpm_bn_init(f), tpm_bn_init(q);
1813       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
1814       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
1815         1, session->DAA_issuerSettings.DAA_generic_q);
1816       tpm_bn_mod(f, f, q);
1817       /* Shift f right by DAA_power0 bits (discard the lowest DAA_power0
1818        * bits) and label the result f1 */
1819       tpm_bn_init(f1);
1820       tpm_bn_fdiv_q_2exp(f1, f, DAA_power0);
1821       /* Set s1 = r1 + (DAA_session->DAA_digest) * f1 in Z */
1822       tpm_bn_init(s1);
1823       tpm_bn_init(tmp);
1824       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
1825         1, session->DAA_session.DAA_digest.digest);
1826       tpm_bn_mul(s1, tmp, f1);
1827       tpm_bn_add(s1, r1, s1);
1828       /* Set outputData = s1 */
1829       tpm_bn_export(scratch, &size, 1, s1);
1830       *outputSize = (uint32_t)size;
1831       tpm_bn_clear(r1), tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(f1);
1832       tpm_bn_clear(s1), tpm_bn_clear(tmp);
1833       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1834         memcpy(*outputData, scratch, *outputSize);
1835       else {
1836         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1837         return TPM_NOSPACE;
1838       }
1839       /* Increment DAA_session->DAA_stage by 1 */
1840       session->DAA_session.DAA_stage++;
1841       /* Return TPM_SUCCESS */
1842       return TPM_SUCCESS;
1843     }
1844     case 19:
1845     {
1846       /* Verify that DAA_session->DAA_stage == 19. Return TPM_DAA_STAGE
1847        * and flush handle on mismatch */
1848       if (session->DAA_session.DAA_stage != 19) {
1849         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1850         return TPM_DAA_STAGE;
1851       }
1852       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1853        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1854        * on mismatch */
1855       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1856         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1857         return TPM_DAA_ISSUER_SETTINGS;
1858       }
1859       /* Verify that DAA_session->DAA_digestContext ==
1860        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1861        * TPM_DAA_TPM_SETTINGS on mismatch */
1862       if (tpm_daa_verify_digestContext(session, &sha1)) {
1863         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1864         return TPM_DAA_TPM_SETTINGS;
1865       }
1866       /* Obtain DAA_SIZE_r2 bits from MGF1("r2",
1867        * DAA_session->DAA_contextSeed), and label them r2 */
1868       memset(scratch, 0, sizeof(scratch));
1869       memcpy(mgf1_seed, "r2", 2);
1870       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1871         sizeof(TPM_NONCE));
1872       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r2);
1873       tpm_bn_init(r2);
1874       tpm_bn_import(r2, DAA_SIZE_r2, 1, scratch);
1875       /* Set s2 = r2 + (DAA_session->DAA_digest) *
1876        * (DAA_joinSession->DAA_join_u0) mod 2^DAA_power1
1877        * (Erase all but the lowest DAA_power1 bits of s2) */
1878       tpm_bn_init(s2);
1879       tpm_bn_import(s2, sizeof(session->DAA_joinSession.DAA_join_u0),
1880         1, session->DAA_joinSession.DAA_join_u0);
1881       tpm_bn_init(tmp);
1882       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
1883         1, session->DAA_session.DAA_digest.digest);
1884       tpm_bn_mul(s2, tmp, s2);
1885       tpm_bn_add(s2, r2, s2);
1886       tpm_bn_ui_pow_ui(tmp, 2, DAA_power1);
1887       tpm_bn_mod(s2, s2, tmp);
1888       /* Set DAA_session->DAA_scratch = s2 */
1889       memset(session->DAA_session.DAA_scratch, 0,
1890         sizeof(session->DAA_session.DAA_scratch));
1891       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, s2);
1892       /* Set outputData = s2 */
1893       tpm_bn_export(scratch, &size, 1, s2);
1894       *outputSize = (uint32_t)size;
1895       tpm_bn_clear(r2), tpm_bn_clear(s2), tpm_bn_clear(tmp);
1896       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1897         memcpy(*outputData, scratch, *outputSize);
1898       else {
1899         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1900         return TPM_NOSPACE;
1901       }
1902       /* Increment DAA_session->DAA_stage by 1 */
1903       session->DAA_session.DAA_stage++;
1904       /* Return TPM_SUCCESS */
1905       return TPM_SUCCESS;
1906     }
1907     case 20:
1908     {
1909       /* Verify that DAA_session->DAA_stage == 20. Return TPM_DAA_STAGE
1910        * and flush handle on mismatch */
1911       if (session->DAA_session.DAA_stage != 20) {
1912         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1913         return TPM_DAA_STAGE;
1914       }
1915       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1916        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1917        * on mismatch */
1918       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1919         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1920         return TPM_DAA_ISSUER_SETTINGS;
1921       }
1922       /* Verify that DAA_session->DAA_digestContext ==
1923        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1924        * TPM_DAA_TPM_SETTINGS on mismatch */
1925       if (tpm_daa_verify_digestContext(session, &sha1)) {
1926         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1927         return TPM_DAA_TPM_SETTINGS;
1928       }
1929       /* Obtain DAA_SIZE_r2 bits from MGF1("r2",
1930        * DAA_session->DAA_contextSeed), and label them r2 */
1931       memset(scratch, 0, sizeof(scratch));
1932       memcpy(mgf1_seed, "r2", 2);
1933       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1934         sizeof(TPM_NONCE));
1935       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r2);
1936       tpm_bn_init(r2);
1937       tpm_bn_import(r2, DAA_SIZE_r2, 1, scratch);
1938       /* Set s12 = r2 + (DAA_session->DAA_digest) *
1939        * (DAA_joinSession->DAA_join_u0) */
1940       tpm_bn_init(s12);
1941       tpm_bn_import(s12, sizeof(session->DAA_joinSession.DAA_join_u0),
1942         1, session->DAA_joinSession.DAA_join_u0);
1943       tpm_bn_init(tmp);
1944       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
1945         1, session->DAA_session.DAA_digest.digest);
1946       tpm_bn_mul(s12, tmp, s12);
1947       tpm_bn_add(s12, r2, s12);
1948       /* Shift s12 right by DAA_power1 bit (discard the lowest DAA_power1
1949        * bits). */
1950       tpm_bn_fdiv_q_2exp(s12, s12, DAA_power1);
1951       /* Set DAA_session->DAA_scratch = s12 */
1952       memset(session->DAA_session.DAA_scratch, 0,
1953         sizeof(session->DAA_session.DAA_scratch));
1954       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, s12);
1955       tpm_bn_clear(r2), tpm_bn_clear(s12), tpm_bn_clear(tmp);
1956       /* Set outputData = DAA_session->DAA_digest */
1957       *outputSize = sizeof(session->DAA_session.DAA_digest.digest);
1958       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
1959         memcpy(*outputData, session->DAA_session.DAA_digest.digest,
1960           *outputSize);
1961       else {
1962         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1963         return TPM_NOSPACE;
1964       }
1965       /* Increment DAA_session->DAA_stage by 1 */
1966       session->DAA_session.DAA_stage++;
1967       /* Return TPM_SUCCESS */
1968       return TPM_SUCCESS;
1969     }
1970     case 21:
1971     {
1972       /* Verify that DAA_session->DAA_stage == 21. Return TPM_DAA_STAGE
1973        * and flush handle on mismatch */
1974       if (session->DAA_session.DAA_stage != 21) {
1975         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1976         return TPM_DAA_STAGE;
1977       }
1978       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
1979        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
1980        * on mismatch */
1981       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
1982         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1983         return TPM_DAA_ISSUER_SETTINGS;
1984       }
1985       /* Verify that DAA_session->DAA_digestContext ==
1986        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
1987        * TPM_DAA_TPM_SETTINGS on mismatch */
1988       if (tpm_daa_verify_digestContext(session, &sha1)) {
1989         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
1990         return TPM_DAA_TPM_SETTINGS;
1991       }
1992       /* Obtain DAA_SIZE_r3 bits from MGF1("r3",
1993        * DAA_session->DAA_contextSeed), and label them r3 */
1994       memset(scratch, 0, sizeof(scratch));
1995       memcpy(mgf1_seed, "r3", 2);
1996       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
1997         sizeof(TPM_NONCE));
1998       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r3);
1999       tpm_bn_init(r3);
2000       tpm_bn_import(r3, DAA_SIZE_r3, 1, scratch);
2001       /* Set s3 = r3 + (DAA_session->DAA_digest) *
2002        * (DAA_joinSession->DAA_join_u1) + (DAA_session->DAA_scratch). */
2003       tpm_bn_init(s3);
2004       tpm_bn_import(s3, sizeof(session->DAA_joinSession.DAA_join_u1),
2005         1, session->DAA_joinSession.DAA_join_u1);
2006       tpm_bn_init(tmp);
2007       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
2008         1, session->DAA_session.DAA_digest.digest);
2009       tpm_bn_mul(s3, tmp, s3);
2010       tpm_bn_add(s3, r3, s3);
2011       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_scratch),
2012         -1, session->DAA_session.DAA_scratch);
2013       tpm_bn_add(s3, s3, tmp);
2014       /* Set DAA_session->DAA_scratch = NULL */
2015       memset(session->DAA_session.DAA_scratch, 0,
2016         sizeof(session->DAA_session.DAA_scratch));
2017       /* Set outputData = s3 */
2018       tpm_bn_export(scratch, &size, 1, s3);
2019       *outputSize = (uint32_t)size;
2020       tpm_bn_clear(r3), tpm_bn_clear(s3), tpm_bn_clear(tmp);
2021       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
2022         memcpy(*outputData, scratch, *outputSize);
2023       else {
2024         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2025         return TPM_NOSPACE;
2026       }
2027       /* Increment DAA_session->DAA_stage by 1 */
2028       session->DAA_session.DAA_stage++;
2029       /* Return TPM_SUCCESS */
2030       return TPM_SUCCESS;
2031     }
2032     case 22:
2033     {
2034       /* Verify that DAA_session->DAA_stage == 22. Return TPM_DAA_STAGE
2035        * and flush handle on mismatch */
2036       if (session->DAA_session.DAA_stage != 22) {
2037         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2038         return TPM_DAA_STAGE;
2039       }
2040       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2041        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2042        * on mismatch */
2043       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2044         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2045         return TPM_DAA_ISSUER_SETTINGS;
2046       }
2047       /* Verify that DAA_session->DAA_digestContext ==
2048        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
2049        * TPM_DAA_TPM_SETTINGS on mismatch */
2050       if (tpm_daa_verify_digestContext(session, &sha1)) {
2051         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2052         return TPM_DAA_TPM_SETTINGS;
2053       }
2054       /* Verify inputSize0 == DAA_SIZE_v0 and return error
2055        * TPM_DAA_INPUT_DATA0 on mismatch */
2056       if (inputSize0 != DAA_SIZE_v0) {
2057         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2058         return TPM_DAA_INPUT_DATA0;
2059       }
2060       /* Set u2 = inputData0 */
2061       tpm_bn_init(u2);
2062       tpm_bn_import(u2, DAA_SIZE_v0, 1, inputData0);
2063       /* Set v0 = u2 + (DAA_joinSession->DAA_join_u0) mod 2^DAA_power1
2064        * (Erase all but the lowest DAA_power1 bits of v0). */
2065       tpm_bn_init(v0);
2066       tpm_bn_import(v0, sizeof(session->DAA_joinSession.DAA_join_u0),
2067         1, session->DAA_joinSession.DAA_join_u0);
2068       tpm_bn_add(v0, u2, v0);
2069       tpm_bn_init(tmp);
2070       tpm_bn_ui_pow_ui(tmp, 2, DAA_power1);
2071       tpm_bn_mod(v0, v0, tmp);
2072       /* Set DAA_tpmSpecific->DAA_digest_v0 = SHA-1(v0) */
2073       tpm_bn_export(scratch, &size, 1, v0);
2074       tpm_sha1_init(&sha1);
2075       tpm_sha1_update(&sha1, (BYTE*) scratch, size);
2076       tpm_sha1_final(&sha1, session->DAA_tpmSpecific.DAA_digest_v0.digest);
2077       /* Set v10 = u2 + (DAA_joinSession->DAA_join_u0) in Z */
2078       tpm_bn_init(v10);
2079       tpm_bn_import(v10, sizeof(session->DAA_joinSession.DAA_join_u0),
2080         1, session->DAA_joinSession.DAA_join_u0);
2081       tpm_bn_add(v10, u2, v10);
2082       /* Shift v10 right by DAA_power1 bits (erase the lowest DAA_power1
2083        * bits). */
2084       tpm_bn_fdiv_q_2exp(v10, v10, DAA_power1);
2085       /* Set DAA_session->DAA_scratch = v10 */
2086       memset(session->DAA_session.DAA_scratch, 0,
2087         sizeof(session->DAA_session.DAA_scratch));
2088       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, v10);
2089       tpm_bn_clear(u2), tpm_bn_clear(v0), tpm_bn_clear(tmp), tpm_bn_clear(v10);
2090       /* Set outputData */
2091         memset(&blob, 0, sizeof(blob));
2092         /* Fill in TPM_DAA_BLOB with a type of TPM_RT_DAA_V0 and encrypt
2093          * the v0 parameters */
2094         blob.tag = TPM_TAG_DAA_BLOB;
2095         blob.resourceType = TPM_RT_DAA_V0;
2096         memset(blob.label, 0, sizeof(blob.label));
2097         memset(&blob.blobIntegrity, 0, sizeof(TPM_DIGEST));
2098         blob.additionalSize = TPM_SYM_KEY_SIZE;
2099         blob.additionalData = tpm_malloc(blob.additionalSize);
2100         if (blob.additionalData == NULL) {
2101           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2102           return TPM_NOSPACE;
2103         }
2104         tpm_get_random_bytes(blob.additionalData, blob.additionalSize);
2105         sensitive.tag = TPM_TAG_DAA_SENSITIVE;
2106         sensitive.internalSize = size;
2107         sensitive.internalData = scratch;
2108         if (encrypt_daa(blob.additionalData, blob.additionalSize,
2109           &sensitive, &blob.sensitiveData, &blob.sensitiveSize)) {
2110             tpm_free(blob.additionalData);
2111             memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2112             return TPM_ENCRYPT_ERROR;
2113         }
2114         if (compute_daa_digest(&blob, &blob.blobIntegrity)) {
2115           debug("TPM_DAA_Join(): compute_daa_digest() failed.");
2116           tpm_free(blob.sensitiveData);
2117           tpm_free(blob.additionalData);
2118           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2119           return TPM_FAIL;
2120         }
2121         /* Set outputData to the encrypted TPM_DAA_BLOB */
2122         *outputSize = sizeof_TPM_DAA_BLOB(blob);
2123         if ((*outputData = tpm_malloc(*outputSize)) == NULL) {
2124           tpm_free(blob.sensitiveData);
2125           tpm_free(blob.additionalData);
2126           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2127           return TPM_NOSPACE;
2128         }
2129         len = *outputSize;
2130         ptr = *outputData;
2131         if (tpm_marshal_TPM_DAA_BLOB(&ptr, &len, &blob)) {
2132           debug("TPM_DAA_Join(): tpm_marshal_TPM_DAA_BLOB() failed.");
2133           tpm_free(blob.sensitiveData);
2134           tpm_free(blob.additionalData);
2135           tpm_free(*outputData);
2136           *outputSize = 0;
2137           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2138           return TPM_FAIL;
2139         }
2140         tpm_free(blob.sensitiveData);
2141         tpm_free(blob.additionalData);
2142       /* Increment DAA_session->DAA_stage by 1 */
2143       session->DAA_session.DAA_stage++;
2144       /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific ||
2145        * DAA_joinSession) */
2146       tpm_daa_update_digestContext(session, &sha1);
2147       /* Return TPM_SUCCESS */
2148       return TPM_SUCCESS;
2149     }
2150     case 23:
2151     {
2152       /* Verify that DAA_session->DAA_stage == 23. Return TPM_DAA_STAGE
2153        * and flush handle on mismatch */
2154       if (session->DAA_session.DAA_stage != 23) {
2155         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2156         return TPM_DAA_STAGE;
2157       }
2158       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2159        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2160        * on mismatch */
2161       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2162         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2163         return TPM_DAA_ISSUER_SETTINGS;
2164       }
2165       /* Verify that DAA_session->DAA_digestContext ==
2166        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
2167        * TPM_DAA_TPM_SETTINGS on mismatch */
2168       if (tpm_daa_verify_digestContext(session, &sha1)) {
2169         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2170         return TPM_DAA_TPM_SETTINGS;
2171       }
2172       /* Verify inputSize0 == DAA_SIZE_v1 and return error
2173        * TPM_DAA_INPUT_DATA0 on mismatch */
2174       if (inputSize0 != DAA_SIZE_v1) {
2175         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2176         return TPM_DAA_INPUT_DATA0;
2177       }
2178       /* Set u3 = inputData0 */
2179       tpm_bn_init(u3);
2180       tpm_bn_import(u3, DAA_SIZE_v1, 1, inputData0);
2181       /* Set v1 = u3 + DAA_joinSession->DAA_join_u1 +
2182        * DAA_session->DAA_scratch */
2183       tpm_bn_init(v1);
2184       tpm_bn_import(v1, sizeof(session->DAA_joinSession.DAA_join_u1),
2185         1, session->DAA_joinSession.DAA_join_u1);
2186       tpm_bn_init(tmp);
2187       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_scratch),
2188         -1, session->DAA_session.DAA_scratch);
2189       tpm_bn_add(v1, v1, tmp);
2190       tpm_bn_add(v1, u3, v1);
2191       /* Set DAA_tpmSpecific->DAA_digest_v1 = SHA-1(v1) */
2192       tpm_bn_export(scratch, &size, 1, v1);
2193       tpm_bn_clear(u3), tpm_bn_clear(v1), tpm_bn_clear(tmp);
2194       tpm_sha1_init(&sha1);
2195       tpm_sha1_update(&sha1, (BYTE*) scratch, size);
2196       tpm_sha1_final(&sha1, session->DAA_tpmSpecific.DAA_digest_v1.digest);
2197       /* Set outputData */
2198         memset(&blob, 0, sizeof(blob));
2199         /* Fill in TPM_DAA_BLOB with a type of TPM_RT_DAA_V1 and encrypt
2200          * the v1 parameters */
2201         blob.tag = TPM_TAG_DAA_BLOB;
2202         blob.resourceType = TPM_RT_DAA_V1;
2203         memset(blob.label, 0, sizeof(blob.label));
2204         memset(&blob.blobIntegrity, 0, sizeof(TPM_DIGEST));
2205         blob.additionalSize = TPM_SYM_KEY_SIZE;
2206         blob.additionalData = tpm_malloc(blob.additionalSize);
2207         if (blob.additionalData == NULL) {
2208           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2209           return TPM_NOSPACE;
2210         }
2211         tpm_get_random_bytes(blob.additionalData, blob.additionalSize);
2212         sensitive.tag = TPM_TAG_DAA_SENSITIVE;
2213         sensitive.internalSize = size;
2214         sensitive.internalData = scratch;
2215         if (encrypt_daa(blob.additionalData, blob.additionalSize,
2216           &sensitive, &blob.sensitiveData, &blob.sensitiveSize)) {
2217             tpm_free(blob.additionalData);
2218             memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2219             return TPM_ENCRYPT_ERROR;
2220         }
2221         if (compute_daa_digest(&blob, &blob.blobIntegrity)) {
2222           debug("TPM_DAA_Join(): compute_daa_digest() failed.");
2223           tpm_free(blob.sensitiveData);
2224           tpm_free(blob.additionalData);
2225           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2226           return TPM_FAIL;
2227         }
2228         /* Set outputData to the encrypted TPM_DAA_BLOB */
2229         *outputSize = sizeof_TPM_DAA_BLOB(blob);
2230         if ((*outputData = tpm_malloc(*outputSize)) == NULL) {
2231           tpm_free(blob.sensitiveData);
2232           tpm_free(blob.additionalData);
2233           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2234           return TPM_NOSPACE;
2235         }
2236         len = *outputSize;
2237         ptr = *outputData;
2238         if (tpm_marshal_TPM_DAA_BLOB(&ptr, &len, &blob)) {
2239           debug("TPM_DAA_Join(): tpm_marshal_TPM_DAA_BLOB() failed.");
2240           tpm_free(blob.sensitiveData);
2241           tpm_free(blob.additionalData);
2242           tpm_free(*outputData);
2243           *outputSize = 0;
2244           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2245           return TPM_FAIL;
2246         }
2247         tpm_free(blob.sensitiveData);
2248         tpm_free(blob.additionalData);
2249       /* Set DAA_session->DAA_scratch = NULL */
2250       memset(session->DAA_session.DAA_scratch, 0,
2251         sizeof(session->DAA_session.DAA_scratch));
2252       /* Increment DAA_session->DAA_stage by 1 */
2253       session->DAA_session.DAA_stage++;
2254       /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific ||
2255        * DAA_joinSession) */
2256       tpm_daa_update_digestContext(session, &sha1);
2257       /* Return TPM_SUCCESS */
2258       return TPM_SUCCESS;
2259     }
2260     case 24:
2261     {
2262       /* Verify that DAA_session->DAA_stage == 24. Return TPM_DAA_STAGE
2263        * and flush handle on mismatch */
2264       if (session->DAA_session.DAA_stage != 24) {
2265         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2266         return TPM_DAA_STAGE;
2267       }
2268       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2269        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2270        * on mismatch */
2271       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2272         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2273         return TPM_DAA_ISSUER_SETTINGS;
2274       }
2275       /* Verify that DAA_session->DAA_digestContext ==
2276        * SHA-1(DAA_tpmSpecific || DAA_joinSession) and return error
2277        * TPM_DAA_TPM_SETTINGS on mismatch */
2278       if (tpm_daa_verify_digestContext(session, &sha1)) {
2279         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2280         return TPM_DAA_TPM_SETTINGS;
2281       }
2282       /* Set outputData = enc(DAA_tpmSpecific) */
2283       memset(&blob, 0, sizeof(blob));
2284       blob.tag = TPM_TAG_DAA_BLOB;
2285       blob.resourceType = TPM_RT_DAA_TPM;
2286       memcpy(blob.label, "DAA_tpmSpecific", 15);
2287       memset(&blob.blobIntegrity, 0, sizeof(TPM_DIGEST));
2288       blob.additionalSize = TPM_SYM_KEY_SIZE;
2289       blob.additionalData = tpm_malloc(blob.additionalSize);
2290       if (blob.additionalData == NULL) {
2291         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2292         return TPM_NOSPACE;
2293       }
2294       tpm_get_random_bytes(blob.additionalData, blob.additionalSize);
2295       sensitive.tag = TPM_TAG_DAA_SENSITIVE;
2296       sensitive.internalSize = len = sizeof(TPM_DAA_TPM);
2297       sensitive.internalData = ptr = tpm_malloc(sensitive.internalSize);
2298       if (sensitive.internalData == NULL) {
2299         tpm_free(blob.additionalData);
2300         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2301         return TPM_NOSPACE;
2302       }
2303       if (tpm_marshal_TPM_DAA_TPM(&ptr, &len, &session->DAA_tpmSpecific)) {
2304         debug("TPM_DAA_Join(): tpm_marshal_TPM_DAA_TPM() failed.");
2305         tpm_free(blob.additionalData);
2306         tpm_free(sensitive.internalData);
2307         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2308         return TPM_FAIL;
2309       }
2310       if (encrypt_daa(blob.additionalData, blob.additionalSize,
2311         &sensitive, &blob.sensitiveData, &blob.sensitiveSize)) {
2312           tpm_free(blob.additionalData);
2313           tpm_free(sensitive.internalData);
2314           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2315           return TPM_ENCRYPT_ERROR;
2316       }
2317       if (compute_daa_digest(&blob, &blob.blobIntegrity)) {
2318         debug("TPM_DAA_Join(): compute_daa_digest() failed.");
2319         tpm_free(blob.sensitiveData);
2320         tpm_free(sensitive.internalData);
2321         tpm_free(blob.additionalData);
2322         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2323         return TPM_FAIL;
2324       }
2325       *outputSize = sizeof_TPM_DAA_BLOB(blob);
2326       if ((*outputData = tpm_malloc(*outputSize)) == NULL) {
2327         tpm_free(blob.sensitiveData);
2328         tpm_free(sensitive.internalData);
2329         tpm_free(blob.additionalData);
2330         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2331         return TPM_NOSPACE;
2332       }
2333       len = *outputSize;
2334       ptr = *outputData;
2335       if (tpm_marshal_TPM_DAA_BLOB(&ptr, &len, &blob)) {
2336         debug("TPM_DAA_Join(): tpm_marshal_TPM_DAA_BLOB() failed.");
2337         tpm_free(blob.sensitiveData);
2338         tpm_free(sensitive.internalData);
2339         tpm_free(blob.additionalData);
2340         tpm_free(*outputData);
2341         *outputSize = 0;
2342         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2343         return TPM_FAIL;
2344       }
2345       tpm_free(blob.sensitiveData);
2346       tpm_free(sensitive.internalData);
2347       tpm_free(blob.additionalData);
2348       /* Terminate the DAA session and all resources assoociated with the
2349        * DAA sign session handle. */
2350       memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2351       /* Return TPM_SUCCESS */
2352       return TPM_SUCCESS;
2353     }
2354     default:
2355       return TPM_DAA_STAGE;
2356   }
2357 }
2358 
TPM_DAA_Sign(TPM_HANDLE handle,BYTE stage,UINT32 inputSize0,BYTE * inputData0,UINT32 inputSize1,BYTE * inputData1,TPM_AUTH * auth1,TPM_COMMAND_CODE * ordinal,UINT32 * outputSize,BYTE ** outputData)2359 TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handle, BYTE stage, UINT32 inputSize0,
2360                         BYTE *inputData0, UINT32 inputSize1,
2361                         BYTE *inputData1, TPM_AUTH *auth1,
2362                         TPM_COMMAND_CODE *ordinal, UINT32 *outputSize,
2363                         BYTE **outputData)
2364 {
2365   BYTE scratch[SCRATCH_SIZE];
2366   TPM_DAA_SESSION_DATA *session = NULL;
2367 
2368   TPM_RESULT res;
2369   tpm_sha1_ctx_t sha1;
2370   BYTE *ptr, *buf;
2371   UINT32 len;
2372   TPM_DAA_BLOB blob;
2373   TPM_DAA_SENSITIVE sensitive;
2374   TPM_DIGEST digest;
2375   BYTE *DAA_generic_R0 = NULL, *DAA_generic_R1 = NULL, *DAA_generic_n = NULL,
2376     *DAA_generic_S0 = NULL, *DAA_generic_S1 = NULL, *DAA_generic_gamma = NULL;
2377   BYTE mgf1_seed[2 + sizeof(TPM_DIGEST)];
2378   tpm_bn_t X, Y, Z, n, w1, w, gamma, q, f, E, r0, r1, r, E1, f0, s0, f1, s1,
2379     r2, s2, s12, r4, s3, tmp;
2380   BYTE selector;
2381   size_t size;
2382   TPM_KEY_DATA *aikData;
2383   TPM_KEY_HANDLE aikHandle;
2384 
2385   info("TPM_DAA_Sign()");
2386   debug("handle = %.8x, stage = %d", handle, stage);
2387   debug("stany.data.currentDAA = %.8x", tpmData.stany.data.currentDAA);
2388 
2389   /* Initalize internal scratch pad */
2390   memset(scratch, 0, SCRATCH_SIZE);
2391 
2392   /* Verify authorization */
2393   res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
2394   if (res != TPM_SUCCESS) return res;
2395 
2396   /* Verify and initalize the session, for all stages greater than zero. */
2397   if (stage > 0) {
2398     if ((HANDLE_TO_INDEX(handle) >= TPM_MAX_SESSIONS_DAA) ||
2399       (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].type !=
2400         TPM_ST_DAA) ||
2401       (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].handle !=
2402       handle)) {
2403         /* Probe, whether the handle from stany.data.currentDAA is valid. */
2404         handle = tpmData.stany.data.currentDAA;
2405         if ((HANDLE_TO_INDEX(handle) >= TPM_MAX_SESSIONS_DAA) ||
2406           (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].type !=
2407             TPM_ST_DAA) ||
2408           (tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)].handle !=
2409             handle))
2410               return TPM_BAD_HANDLE;
2411     }
2412     session = &tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)];
2413   }
2414 
2415   /* TPM_DAA_SIGN [TPM_Part3], Section 26.2, Rev. 85 */
2416   switch (stage) {
2417     case 0:
2418     {
2419       /* Determine that sufficient resources are available to perform a
2420        * DAA_Sign. Assign session handle for this DAA_Sign. */
2421       handle = tpm_get_free_daa_session();
2422       if (handle == TPM_INVALID_HANDLE)
2423         return TPM_RESOURCES;
2424       session = &tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(handle)];
2425       /* Verify that sizeOf(inputData0) == sizeOf(TPM_DAA_ISSUER)
2426        * and return error TPM_DAA_INPUT_DATA0 on mismatch */
2427       if (inputSize0 != sizeof(TPM_DAA_ISSUER)) {
2428         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2429         return TPM_DAA_INPUT_DATA0;
2430       }
2431       /* Set DAA_issuerSettings = inputData0. */
2432       /* Verify that all fields in DAA_issuerSettings are present and
2433        * return error TPM_DAA_INPUT_DATA0 if not. */
2434       ptr = inputData0, len = inputSize0;
2435       if (tpm_unmarshal_TPM_DAA_ISSUER(&ptr, &len,
2436         &session->DAA_issuerSettings) || (len != 0) ||
2437         (session->DAA_issuerSettings.tag != TPM_TAG_DAA_ISSUER)) {
2438           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2439           return TPM_DAA_INPUT_DATA0;
2440       }
2441       /* Set all fields in DAA_session = NULL */
2442       memset(&session->DAA_session, 0, sizeof(TPM_DAA_CONTEXT));
2443       /* Assign new handle for session */
2444       tpmData.stany.data.currentDAA = handle;
2445       debug("TPM_DAA_Sign() -- set handle := %.8x", handle);
2446       /* Set outputData to new handle */
2447       *outputSize = sizeof(TPM_HANDLE);
2448       if ((*outputData = tpm_malloc(*outputSize)) != NULL) {
2449         ptr = *outputData, len = *outputSize;
2450         if (tpm_marshal_TPM_HANDLE(&ptr, &len, handle)) {
2451           debug("TPM_DAA_Sign(): tpm_marshal_TPM_HANDLE() failed.");
2452           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2453           return TPM_FAIL;
2454         }
2455       } else {
2456         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2457         return TPM_NOSPACE;
2458       }
2459       /* Set DAA_session->DAA_stage = 1 */
2460       session->DAA_session.DAA_stage = 1;
2461       /* Return TPM_SUCCESS */
2462       return TPM_SUCCESS;
2463     }
2464     case 1:
2465     {
2466       /* Verify that DAA_session->DAA_stage == 1. Return TPM_DAA_STAGE and
2467        * flush handle on mismatch */
2468       if (session->DAA_session.DAA_stage != 1) {
2469         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2470         return TPM_DAA_STAGE;
2471       }
2472       /* Set DAA_tpmSpecific = unwrap(inputData0) */
2473       ptr = inputData0, len = inputSize0;
2474       if (tpm_unmarshal_TPM_DAA_BLOB(&ptr, &len, &blob) || (len != 0)) {
2475         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2476         return TPM_DAA_INPUT_DATA0;
2477       }
2478       sensitive.internalData = scratch;
2479       if (decrypt_daa(blob.additionalData, blob.additionalSize,
2480         blob.sensitiveData, blob.sensitiveSize, &sensitive, &buf)) {
2481           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2482           return TPM_DECRYPT_ERROR;
2483       }
2484       if (compute_daa_digest(&blob, &digest) ||
2485         memcmp(&digest, &blob.blobIntegrity, sizeof(TPM_DIGEST))) {
2486           tpm_free(buf);
2487           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2488           return TPM_DAA_INPUT_DATA0;
2489       }
2490       if ((blob.resourceType != TPM_RT_DAA_TPM) ||
2491         (sensitive.tag != TPM_TAG_DAA_SENSITIVE ||
2492         (sensitive.internalSize != sizeof(TPM_DAA_TPM)))) {
2493           tpm_free(buf);
2494           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2495           return TPM_DAA_INPUT_DATA0;
2496       }
2497       if (tpm_unmarshal_TPM_DAA_TPM(&sensitive.internalData,
2498         &sensitive.internalSize, &session->DAA_tpmSpecific)) {
2499           tpm_free(buf);
2500           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2501           return TPM_DAA_INPUT_DATA0;
2502       }
2503       tpm_free(buf);
2504 
2505       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2506        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2507        * on mismatch */
2508       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2509         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2510         return TPM_DAA_ISSUER_SETTINGS;
2511       }
2512       /* Set DAA_session->DAA_digestContext = SHA-1(DAA_tpmSpecific) */
2513       tpm_daa_update_digestContext_sign(session, &sha1);
2514       /* Obtain random data from the RNG and store it as
2515        * DAA_session->DAA_contextSeed */
2516       tpm_get_random_bytes(session->DAA_session.DAA_contextSeed.nonce,
2517         sizeof(TPM_NONCE));
2518       /* Set outputData = NULL */
2519       *outputSize = 0, *outputData = NULL;
2520       /* Set DAA_session->DAA_stage = 2 */
2521       session->DAA_session.DAA_stage = 2;
2522       /* Return TPM_SUCCESS */
2523       return TPM_SUCCESS;
2524     }
2525     case 2:
2526     {
2527       /* Verify that DAA_session->DAA_stage == 2. Return TPM_DAA_STAGE and
2528        * flush handle on mismatch */
2529       if (session->DAA_session.DAA_stage != 2) {
2530         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2531         return TPM_DAA_STAGE;
2532       }
2533       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2534        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2535        * on mismatch */
2536       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2537         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2538         return TPM_DAA_ISSUER_SETTINGS;
2539       }
2540       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
2541        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
2542       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
2543         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2544         return TPM_DAA_TPM_SETTINGS;
2545       }
2546       /* Set DAA_generic_R0 = inputData0 */
2547       DAA_generic_R0 = inputData0;
2548       /* Verify that SHA-1(DAA_generic_R0) ==
2549        * DAA_issuerSettings->DAA_digest_R0 and return error
2550        * TPM_DAA_INPUT_DATA0 on mismatch */
2551       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_R0,
2552         DAA_generic_R0, inputSize0, &sha1)) {
2553           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2554           return TPM_DAA_INPUT_DATA0;
2555       }
2556       /* Set DAA_generic_n = inputData1 */
2557       DAA_generic_n = inputData1;
2558       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
2559        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
2560       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
2561         DAA_generic_n, inputSize1, &sha1)) {
2562           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2563           return TPM_DAA_INPUT_DATA1;
2564       }
2565       /* Obtain DAA_SIZE_r0 bits from MGF1("r0",
2566        * DAA_session->DAA_contextSeed), and label them Y */
2567       memset(scratch, 0, sizeof(scratch));
2568       memcpy(mgf1_seed, "r0", 2);
2569       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
2570         sizeof(TPM_NONCE));
2571       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r0);
2572       tpm_bn_init(Y);
2573       tpm_bn_import(Y, DAA_SIZE_r0, 1, scratch);
2574       /* Set X = DAA_generic_R0 */
2575       tpm_bn_init(X);
2576       tpm_bn_import(X, inputSize0, 1, DAA_generic_R0);
2577       /* Set n = DAA_generic_n */
2578       tpm_bn_init(n);
2579       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
2580       /* Set DAA_session->DAA_scratch = (X^Y) mod n */
2581       memset(session->DAA_session.DAA_scratch, 0,
2582         sizeof(session->DAA_session.DAA_scratch));
2583       tpm_bn_init(tmp);
2584       tpm_bn_powm(tmp, X, Y, n);
2585       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
2586       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(n), tpm_bn_clear(tmp);
2587       /* Set outputData = NULL */
2588       *outputSize = 0, *outputData = NULL;
2589       /* Increment DAA_session->DAA_stage by 1 */
2590       session->DAA_session.DAA_stage++;
2591       /* Return TPM_SUCCESS */
2592       return TPM_SUCCESS;
2593     }
2594     case 3:
2595     {
2596       /* Verify that DAA_session->DAA_stage == 3. Return TPM_DAA_STAGE
2597        * and flush handle on mismatch */
2598       if (session->DAA_session.DAA_stage != 3) {
2599         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2600         return TPM_DAA_STAGE;
2601       }
2602       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2603        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2604        * on mismatch */
2605       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2606         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2607         return TPM_DAA_ISSUER_SETTINGS;
2608       }
2609       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
2610        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
2611       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
2612         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2613         return TPM_DAA_TPM_SETTINGS;
2614       }
2615       /* Set DAA_generic_R1 = inputData0 */
2616       DAA_generic_R1 = inputData0;
2617       /* Verify that SHA-1(DAA_generic_R1) ==
2618        * DAA_issuerSettings->DAA_digest_R1 and return error
2619        * TPM_DAA_INPUT_DATA0 on mismatch */
2620       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_R1,
2621         DAA_generic_R1, inputSize0, &sha1)) {
2622           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2623           return TPM_DAA_INPUT_DATA0;
2624       }
2625       /* Set DAA_generic_n = inputData1 */
2626       DAA_generic_n = inputData1;
2627       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
2628        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
2629       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
2630         DAA_generic_n, inputSize1, &sha1)) {
2631           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2632           return TPM_DAA_INPUT_DATA1;
2633       }
2634       /* Obtain DAA_SIZE_r1 bits from MGF1("r1",
2635        * DAA_session->DAA_contextSeed), and label them Y */
2636       memset(scratch, 0, sizeof(scratch));
2637       memcpy(mgf1_seed, "r1", 2);
2638       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
2639         sizeof(TPM_NONCE));
2640       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r1);
2641       tpm_bn_init(Y);
2642       tpm_bn_import(Y, DAA_SIZE_r1, 1, scratch);
2643       /* Set X = DAA_generic_R1 */
2644       tpm_bn_init(X);
2645       tpm_bn_import(X, inputSize0, 1, DAA_generic_R1);
2646       /* Set n = DAA_generic_n */
2647       tpm_bn_init(n);
2648       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
2649       /* Set Z = DAA_session->DAA_scratch */
2650       tpm_bn_init(Z);
2651       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
2652         session->DAA_session.DAA_scratch);
2653       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
2654       memset(session->DAA_session.DAA_scratch, 0,
2655         sizeof(session->DAA_session.DAA_scratch));
2656       tpm_bn_init(tmp);
2657       tpm_bn_powm(tmp, X, Y, n);
2658       tpm_bn_mul(tmp, tmp, Z);
2659       tpm_bn_mod(tmp, tmp, n);
2660       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
2661       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
2662       /* Set outputData = NULL */
2663       *outputSize = 0, *outputData = NULL;
2664       /* Increment DAA_session->DAA_stage by 1 */
2665       session->DAA_session.DAA_stage++;
2666       /* Return TPM_SUCCESS */
2667       return TPM_SUCCESS;
2668     }
2669     case 4:
2670     {
2671       /* Verify that DAA_session->DAA_stage == 4. Return TPM_DAA_STAGE
2672        * and flush handle on mismatch */
2673       if (session->DAA_session.DAA_stage != 4) {
2674         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2675         return TPM_DAA_STAGE;
2676       }
2677       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2678        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2679        * on mismatch */
2680       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2681         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2682         return TPM_DAA_ISSUER_SETTINGS;
2683       }
2684       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
2685        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
2686       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
2687         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2688         return TPM_DAA_TPM_SETTINGS;
2689       }
2690       /* Set DAA_generic_S0 = inputData0 */
2691       DAA_generic_S0 = inputData0;
2692       /* Verify that SHA-1(DAA_generic_S0) ==
2693        * DAA_issuerSettings->DAA_digest_S0 and return error
2694        * TPM_DAA_INPUT_DATA0 on mismatch */
2695       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_S0,
2696         DAA_generic_S0, inputSize0, &sha1)) {
2697           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2698           return TPM_DAA_INPUT_DATA0;
2699       }
2700       /* Set DAA_generic_n = inputData1 */
2701       DAA_generic_n = inputData1;
2702       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
2703        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
2704       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
2705         DAA_generic_n, inputSize1, &sha1)) {
2706           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2707           return TPM_DAA_INPUT_DATA1;
2708       }
2709       /* Obtain DAA_SIZE_r2 bits from MGF1("r2",
2710        * DAA_session->DAA_contextSeed), and label them Y */
2711       memset(scratch, 0, sizeof(scratch));
2712       memcpy(mgf1_seed, "r2", 2);
2713       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
2714         sizeof(TPM_NONCE));
2715       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r2);
2716       tpm_bn_init(Y);
2717       tpm_bn_import(Y, DAA_SIZE_r2, 1, scratch);
2718       /* Set X = DAA_generic_S0 */
2719       tpm_bn_init(X);
2720       tpm_bn_import(X, inputSize0, 1, DAA_generic_S0);
2721       /* Set n = DAA_generic_n */
2722       tpm_bn_init(n);
2723       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
2724       /* Set Z = DAA_session->DAA_scratch */
2725       tpm_bn_init(Z);
2726       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
2727         session->DAA_session.DAA_scratch);
2728       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
2729       memset(session->DAA_session.DAA_scratch, 0,
2730         sizeof(session->DAA_session.DAA_scratch));
2731       tpm_bn_init(tmp);
2732       tpm_bn_powm(tmp, X, Y, n);
2733       tpm_bn_mul(tmp, tmp, Z);
2734       tpm_bn_mod(tmp, tmp, n);
2735       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, tmp);
2736       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
2737       /* Set outputData = NULL */
2738       *outputSize = 0, *outputData = NULL;
2739       /* Increment DAA_session->DAA_stage by 1 */
2740       session->DAA_session.DAA_stage++;
2741       /* Return TPM_SUCCESS */
2742       return TPM_SUCCESS;
2743     }
2744     case 5:
2745     {
2746       /* Verify that DAA_session->DAA_stage == 5. Return TPM_DAA_STAGE
2747        * and flush handle on mismatch */
2748       if (session->DAA_session.DAA_stage != 5) {
2749         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2750         return TPM_DAA_STAGE;
2751       }
2752       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2753        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2754        * on mismatch */
2755       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2756         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2757         return TPM_DAA_ISSUER_SETTINGS;
2758       }
2759       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
2760        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
2761       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
2762         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2763         return TPM_DAA_TPM_SETTINGS;
2764       }
2765       /* Set DAA_generic_S1 = inputData0 */
2766       DAA_generic_S1 = inputData0;
2767       /* Verify that SHA-1(DAA_generic_S1) ==
2768        * DAA_issuerSettings->DAA_digest_S1 and return error
2769        * TPM_DAA_INPUT_DATA0 on mismatch */
2770       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_S1,
2771         DAA_generic_S1, inputSize0, &sha1)) {
2772           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2773           return TPM_DAA_INPUT_DATA0;
2774       }
2775       /* Set DAA_generic_n = inputData1 */
2776       DAA_generic_n = inputData1;
2777       /* Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings->DAA_digest_n
2778        * and return error TPM_DAA_INPUT_DATA1 on mismatch */
2779       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_n,
2780         DAA_generic_n, inputSize1, &sha1)) {
2781           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2782           return TPM_DAA_INPUT_DATA1;
2783       }
2784       /* Obtain DAA_SIZE_r4 bits from MGF1("r4",
2785        * DAA_session->DAA_contextSeed), and label them Y */
2786       memset(scratch, 0, sizeof(scratch));
2787       memcpy(mgf1_seed, "r4", 2);
2788       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
2789         sizeof(TPM_NONCE));
2790       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r4);
2791       tpm_bn_init(Y);
2792       tpm_bn_import(Y, DAA_SIZE_r4, 1, scratch);
2793       /* Set X = DAA_generic_S1 */
2794       tpm_bn_init(X);
2795       tpm_bn_import(X, inputSize0, 1, DAA_generic_S1);
2796       /* Set n = DAA_generic_n */
2797       tpm_bn_init(n);
2798       tpm_bn_import(n, inputSize1, 1, DAA_generic_n);
2799       /* Set Z = DAA_session->DAA_scratch */
2800       tpm_bn_init(Z);
2801       tpm_bn_import(Z, sizeof(session->DAA_session.DAA_scratch), -1,
2802         session->DAA_session.DAA_scratch);
2803       /* Set DAA_session->DAA_scratch = Z*(X^Y) mod n */
2804       memset(session->DAA_session.DAA_scratch, 0,
2805         sizeof(session->DAA_session.DAA_scratch));
2806       tpm_bn_init(tmp);
2807       tpm_bn_powm(tmp, X, Y, n);
2808       tpm_bn_mul(tmp, tmp, Z);
2809       tpm_bn_mod(tmp, tmp, n);
2810       tpm_bn_export(session->DAA_session.DAA_scratch, &size, 1, tmp);
2811       *outputSize = (uint32_t)size;
2812       tpm_bn_clear(X), tpm_bn_clear(Y), tpm_bn_clear(Z), tpm_bn_clear(n), tpm_bn_clear(tmp);
2813       /* Set outputData = DAA_session->DAA_scratch */
2814       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
2815         memcpy(*outputData, session->DAA_session.DAA_scratch, *outputSize);
2816       else {
2817         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2818         return TPM_NOSPACE;
2819       }
2820       /* Set DAA_session->DAA_scratch = NULL */
2821       memset(session->DAA_session.DAA_scratch, 0,
2822         sizeof(session->DAA_session.DAA_scratch));
2823       /* Increment DAA_session->DAA_stage by 1 */
2824       session->DAA_session.DAA_stage++;
2825       /* Return TPM_SUCCESS */
2826       return TPM_SUCCESS;
2827     }
2828     case 6:
2829     {
2830       /* Verify that DAA_session->DAA_stage == 6. Return TPM_DAA_STAGE
2831        * and flush handle on mismatch */
2832       if (session->DAA_session.DAA_stage != 6) {
2833         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2834         return TPM_DAA_STAGE;
2835       }
2836       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2837        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2838        * on mismatch */
2839       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2840         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2841         return TPM_DAA_ISSUER_SETTINGS;
2842       }
2843       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
2844        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
2845       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
2846         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2847         return TPM_DAA_TPM_SETTINGS;
2848       }
2849       /* Set DAA_generic_gamma = inputData0 */
2850       DAA_generic_gamma = inputData0;
2851       /* Verify that SHA-1(DAA_generic_gamma) ==
2852        * DAA_issuerSettings->DAA_digest_gamma and return error
2853        * TPM_DAA_INPUT_DATA0 on mismatch */
2854       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_gamma,
2855         DAA_generic_gamma, inputSize0, &sha1)) {
2856           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2857           return TPM_DAA_INPUT_DATA0;
2858       }
2859       /* Verify that inputSize1 == DAA_SIZE_w and return error
2860        * TPM_DAA_INPUT_DATA1 on mismatch */
2861       if (inputSize1 != DAA_SIZE_w) {
2862         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2863         return TPM_DAA_INPUT_DATA1;
2864       }
2865       /* Set w = inputData1 */
2866       tpm_bn_init(w);
2867       tpm_bn_import(w, inputSize1, 1, inputData1);
2868       /* Set w1 = w^(DAA_issuerSettings->DAA_generic_q) mod
2869        * (DAA_generic_gamma) */
2870       tpm_bn_init(gamma);
2871       tpm_bn_import(gamma, inputSize0, 1, DAA_generic_gamma);
2872       tpm_bn_init(q);
2873       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
2874         1, session->DAA_issuerSettings.DAA_generic_q);
2875       tpm_bn_init(w1);
2876       tpm_bn_powm(w1, w, q, gamma);
2877       /* If w1 != 1 (unity), return error TPM_DAA_WRONG_W */
2878       if (tpm_bn_cmp_ui(w1, 1)) {
2879         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2880         return TPM_DAA_WRONG_W;
2881       }
2882       /* Set DAA_session->DAA_scratch = w */
2883       memset(session->DAA_session.DAA_scratch, 0,
2884         sizeof(session->DAA_session.DAA_scratch));
2885       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, w);
2886       tpm_bn_clear(w), tpm_bn_clear(gamma), tpm_bn_clear(w1), tpm_bn_clear(q);
2887       /* Set outputData = NULL */
2888       *outputSize = 0, *outputData = NULL;
2889       /* Increment DAA_session->DAA_stage by 1 */
2890       session->DAA_session.DAA_stage++;
2891       /* Return TPM_SUCCESS */
2892       return TPM_SUCCESS;
2893     }
2894     case 7:
2895     {
2896       /* Verify that DAA_session->DAA_stage == 7. Return TPM_DAA_STAGE
2897        * and flush handle on mismatch */
2898       if (session->DAA_session.DAA_stage != 7) {
2899         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2900         return TPM_DAA_STAGE;
2901       }
2902       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2903        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2904        * on mismatch */
2905       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2906         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2907         return TPM_DAA_ISSUER_SETTINGS;
2908       }
2909       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
2910        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
2911       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
2912         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2913         return TPM_DAA_TPM_SETTINGS;
2914       }
2915       /* Set DAA_generic_gamma = inputData0 */
2916       DAA_generic_gamma = inputData0;
2917       /* Verify that SHA-1(DAA_generic_gamma) ==
2918        * DAA_issuerSettings->DAA_digest_gamma and return error
2919        * TPM_DAA_INPUT_DATA0 on mismatch */
2920       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_gamma,
2921         DAA_generic_gamma, inputSize0, &sha1)) {
2922           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2923           return TPM_DAA_INPUT_DATA0;
2924       }
2925       /* Set f = SHA-1(DAA_tpmSpecific->DAA_rekey ||
2926        * DAA_tpmSpecific->DAA_count || 0) || SHA-1(DAA_tpmSpecific->DAA_rekey
2927        * || DAA_tpmSpecific->DAA_count || 1) mod
2928        * DAA_issuerSettings->DAA_generic_q. */
2929       tpm_sha1_init(&sha1);
2930       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
2931           sizeof(session->DAA_tpmSpecific.DAA_rekey));
2932       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
2933           sizeof(session->DAA_tpmSpecific.DAA_count));
2934       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
2935       tpm_sha1_final(&sha1, scratch);
2936       tpm_sha1_init(&sha1);
2937       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
2938           sizeof(session->DAA_tpmSpecific.DAA_rekey));
2939       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
2940           sizeof(session->DAA_tpmSpecific.DAA_count));
2941       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
2942       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
2943       tpm_bn_init(f), tpm_bn_init(q);
2944       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
2945       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
2946         1, session->DAA_issuerSettings.DAA_generic_q);
2947       tpm_bn_mod(f, f, q);
2948       /* Set E = ((DAA_session->DAA_scratch)^f) mod (DAA_generic_gamma).*/
2949       tpm_bn_init(gamma);
2950       tpm_bn_import(gamma, inputSize0, 1, DAA_generic_gamma);
2951       tpm_bn_init(w);
2952       tpm_bn_import(w, sizeof(session->DAA_session.DAA_scratch), -1,
2953         session->DAA_session.DAA_scratch);
2954       tpm_bn_init(E);
2955       tpm_bn_powm(E, w, f, gamma);
2956       /* Set outputData = E */
2957       tpm_bn_export(scratch, &size, 1, E);
2958       *outputSize = (uint32_t)size;
2959       tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(gamma), tpm_bn_clear(w), tpm_bn_clear(E);
2960       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
2961         memcpy(*outputData, scratch, *outputSize);
2962       else {
2963         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2964         return TPM_NOSPACE;
2965       }
2966       /* Increment DAA_session->DAA_stage by 1 */
2967       session->DAA_session.DAA_stage++;
2968       /* Return TPM_SUCCESS */
2969       return TPM_SUCCESS;
2970     }
2971     case 8:
2972     {
2973       /* Verify that DAA_session->DAA_stage == 8. Return TPM_DAA_STAGE
2974        * and flush handle on mismatch */
2975       if (session->DAA_session.DAA_stage != 8) {
2976         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2977         return TPM_DAA_STAGE;
2978       }
2979       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
2980        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
2981        * on mismatch */
2982       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
2983         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2984         return TPM_DAA_ISSUER_SETTINGS;
2985       }
2986       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
2987        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
2988       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
2989         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
2990         return TPM_DAA_TPM_SETTINGS;
2991       }
2992       /* Set DAA_generic_gamma = inputData0 */
2993       DAA_generic_gamma = inputData0;
2994       /* Verify that SHA-1(DAA_generic_gamma) ==
2995        * DAA_issuerSettings->DAA_digest_gamma and return error
2996        * TPM_DAA_INPUT_DATA0 on mismatch */
2997       if (tpm_daa_verify_generic(session->DAA_issuerSettings.DAA_digest_gamma,
2998         DAA_generic_gamma, inputSize0, &sha1)) {
2999           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3000           return TPM_DAA_INPUT_DATA0;
3001       }
3002       /* Obtain DAA_SIZE_r0 bits from MGF1("r0",
3003        * DAA_session->DAA_contextSeed), and label them r0 */
3004       memset(scratch, 0, sizeof(scratch));
3005       memcpy(mgf1_seed, "r0", 2);
3006       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
3007         sizeof(TPM_NONCE));
3008       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r0);
3009       tpm_bn_init(r0);
3010       tpm_bn_import(r0, DAA_SIZE_r0, 1, scratch);
3011       /* Obtain DAA_SIZE_r1 bits from MGF1("r1",
3012        * DAA_session->DAA_contextSeed), and label them r1 */
3013       memset(scratch, 0, sizeof(scratch));
3014       memcpy(mgf1_seed, "r1", 2);
3015       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
3016         sizeof(TPM_NONCE));
3017       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r1);
3018       tpm_bn_init(r1);
3019       tpm_bn_import(r1, DAA_SIZE_r1, 1, scratch);
3020       /* Set r = r0 + 2^DAA_power0 * r1 mod
3021        * (DAA_issuerSettings->DAA_generic_q). */
3022       tpm_bn_init(q);
3023       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
3024         1, session->DAA_issuerSettings.DAA_generic_q);
3025       tpm_bn_init(r);
3026       tpm_bn_ui_pow_ui(r, 2, DAA_power0);
3027       tpm_bn_mul(r, r, r1);
3028       tpm_bn_mod(r, r, q);
3029       tpm_bn_add(r, r, r0);
3030       tpm_bn_mod(r, r, q);
3031       /* Set E1 = ((DAA_session->DAA_scratch)^r) mod (DAA_generic_gamma). */
3032       tpm_bn_init(gamma);
3033       tpm_bn_import(gamma, inputSize0, 1, DAA_generic_gamma);
3034       tpm_bn_init(w);
3035       tpm_bn_import(w, sizeof(session->DAA_session.DAA_scratch), -1,
3036         session->DAA_session.DAA_scratch);
3037       tpm_bn_init(E1);
3038       tpm_bn_powm(E1, w, r, gamma);
3039       /* Set DAA_session->DAA_scratch = NULL */
3040       memset(session->DAA_session.DAA_scratch, 0,
3041         sizeof(session->DAA_session.DAA_scratch));
3042       /* Set outputData = E1 */
3043       tpm_bn_export(scratch, &size, 1, E1);
3044       *outputSize = (uint32_t)size;
3045       tpm_bn_clear(r0), tpm_bn_clear(r1), tpm_bn_clear(q), tpm_bn_clear(r);
3046       tpm_bn_clear(gamma), tpm_bn_clear(w), tpm_bn_clear(E1);
3047       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
3048         memcpy(*outputData, scratch, *outputSize);
3049       else {
3050         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3051         return TPM_NOSPACE;
3052       }
3053       /* Increment DAA_session->DAA_stage by 1 */
3054       session->DAA_session.DAA_stage++;
3055       /* Return TPM_SUCCESS */
3056       return TPM_SUCCESS;
3057     }
3058     case 9:
3059     {
3060       BYTE *NT = NULL;
3061 
3062       /* Verify that DAA_session->DAA_stage == 9. Return TPM_DAA_STAGE
3063        * and flush handle on mismatch */
3064       if (session->DAA_session.DAA_stage != 9) {
3065         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3066         return TPM_DAA_STAGE;
3067       }
3068       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
3069        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
3070        * on mismatch */
3071       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
3072         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3073         return TPM_DAA_ISSUER_SETTINGS;
3074       }
3075       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
3076        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
3077       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
3078         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3079         return TPM_DAA_TPM_SETTINGS;
3080       }
3081       /* Verify that inputSize0 == sizeOf(TPM_DIGEST) and return error
3082        * TPM_DAA_INPUT_DATA0 on mismatch */
3083       if (inputSize0 != sizeof(TPM_DIGEST)) {
3084         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3085         return TPM_DAA_INPUT_DATA0;
3086       }
3087       /* Set DAA_session->DAA_digest = inputData0 */
3088       memcpy(&session->DAA_session.DAA_digest, inputData0, inputSize0);
3089       /* Obtain DAA_SIZE_NT bytes from the RNG and label them NT */
3090       if ((NT = tpm_malloc(DAA_SIZE_NT)) == NULL) {
3091         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3092         return TPM_NOSPACE;
3093       }
3094       tpm_get_random_bytes(NT, DAA_SIZE_NT);
3095       /* Set DAA_session->DAA_digest to the SHA-1(DAA_session->DAA_digest ||
3096        * NT)*/
3097       tpm_sha1_init(&sha1);
3098       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest,
3099           sizeof(session->DAA_session.DAA_digest));
3100       tpm_sha1_update(&sha1, NT, DAA_SIZE_NT);
3101       tpm_sha1_final(&sha1, session->DAA_session.DAA_digest.digest);
3102       /* Set outputData = NT */
3103       *outputSize = DAA_SIZE_NT;
3104       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
3105         memcpy(*outputData, NT, *outputSize);
3106       else {
3107         tpm_free(NT);
3108         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3109         return TPM_NOSPACE;
3110       }
3111       tpm_free(NT);
3112       /* Increment DAA_session->DAA_stage by 1 */
3113       session->DAA_session.DAA_stage++;
3114       /* Return TPM_SUCCESS */
3115       return TPM_SUCCESS;
3116     }
3117     case 10:
3118     {
3119       /* Verify that DAA_session->DAA_stage == 10. Return TPM_DAA_STAGE
3120        * and flush handle on mismatch */
3121       if (session->DAA_session.DAA_stage != 10) {
3122         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3123         return TPM_DAA_STAGE;
3124       }
3125       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
3126        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
3127        * on mismatch */
3128       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
3129         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3130         return TPM_DAA_ISSUER_SETTINGS;
3131       }
3132       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
3133        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
3134       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
3135         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3136         return TPM_DAA_TPM_SETTINGS;
3137       }
3138       /* Set selector = inputData0, verify that selector == 0 or 1, and
3139        * return error TPM_DAA_INPUT_DATA0 on mismatch */
3140       if (inputSize0 != sizeof(selector)) {
3141         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3142         return TPM_DAA_INPUT_DATA0;
3143       }
3144       memcpy(&selector, inputData0, sizeof(selector));
3145       if ((selector != '\x00') && (selector != '\x01')) {
3146         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3147         return TPM_DAA_INPUT_DATA0;
3148       }
3149       /* If selector == 1, verify that inputSize1 == sizeOf(TPM_DIGEST), and */
3150       if (selector == '\x01') {
3151         debug("DAA_Sign(): selector == 1");
3152         if (inputSize1 != sizeof(TPM_DIGEST)) {
3153           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3154           return TPM_DAA_INPUT_DATA1;
3155         }
3156         /* Set DAA_session->DAA_digest to SHA-1(DAA_session->DAA_digest ||
3157          * 1 || inputData1) */
3158         tpm_sha1_init(&sha1);
3159         tpm_sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest,
3160           sizeof(session->DAA_session.DAA_digest));
3161         tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
3162         tpm_sha1_update(&sha1, inputData1, inputSize1);
3163         tpm_sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
3164       }
3165       /* If selector == 0, verify that inputData1 is a handle to a TPM
3166        * identity key (AIK), and */
3167       if (selector == '\x00') {
3168         debug("DAA_Sign(): selector == 0");
3169         if (tpm_unmarshal_TPM_KEY_HANDLE(&inputData1, &inputSize1,
3170           &aikHandle) || (inputSize1 != 0))
3171         {
3172           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3173           return TPM_DAA_INPUT_DATA1;
3174         }
3175         debug("DAA_Sign(): aikHandle == %.8x", aikHandle);
3176         aikData = tpm_get_key(aikHandle);
3177         if (aikData == NULL) {
3178           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3179           return TPM_DAA_INPUT_DATA1;
3180         }
3181         if (aikData->keyUsage != TPM_KEY_IDENTITY) {
3182           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3183           return TPM_DAA_INPUT_DATA1;
3184         }
3185         /* Set DAA_session->DAA_digest to SHA-1(DAA_session->DAA_digest ||
3186          * 0 || n2) where n2 is the modulus of the AIK */
3187         tpm_sha1_init(&sha1);
3188         tpm_sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest,
3189           sizeof(session->DAA_session.DAA_digest));
3190         tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
3191         tpm_rsa_export_modulus(&aikData->key, scratch, &size);
3192         tpm_sha1_update(&sha1, scratch, size);
3193         tpm_sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
3194       }
3195       /* Set outputData = DAA_session->DAA_digest */
3196       *outputSize = sizeof(session->DAA_session.DAA_digest);
3197       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
3198         memcpy(*outputData, &session->DAA_session.DAA_digest, *outputSize);
3199       else {
3200         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3201         return TPM_NOSPACE;
3202       }
3203       /* Increment DAA_session->DAA_stage by 1 */
3204       session->DAA_session.DAA_stage++;
3205       /* Return TPM_SUCCESS */
3206       return TPM_SUCCESS;
3207     }
3208     case 11:
3209     {
3210       /* Verify that DAA_session->DAA_stage == 11. Return TPM_DAA_STAGE
3211        * and flush handle on mismatch */
3212       if (session->DAA_session.DAA_stage != 11) {
3213         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3214         return TPM_DAA_STAGE;
3215       }
3216       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
3217        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
3218        * on mismatch */
3219       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
3220         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3221         return TPM_DAA_ISSUER_SETTINGS;
3222       }
3223       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
3224        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
3225       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
3226         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3227         return TPM_DAA_TPM_SETTINGS;
3228       }
3229       /* Obtain DAA_SIZE_r0 bits from MGF1("r0",
3230        * DAA_session->DAA_contextSeed), and label them r0 */
3231       memset(scratch, 0, sizeof(scratch));
3232       memcpy(mgf1_seed, "r0", 2);
3233       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
3234         sizeof(TPM_NONCE));
3235       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r0);
3236       tpm_bn_init(r0);
3237       tpm_bn_import(r0, DAA_SIZE_r0, 1, scratch);
3238       /* Set f = SHA1(DAA_tpmSpecific->DAA_rekey ||
3239        * DAA_tpmSpecific->DAA_count || 0 ) ||
3240        * SHA1(DAA_tpmSpecific->DAA_rekey || DAA_tpmSpecific->DAA_count ||
3241        * 1 ) mod DAA_issuerSettings->DAA_generic_q */
3242       tpm_sha1_init(&sha1);
3243       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
3244           sizeof(session->DAA_tpmSpecific.DAA_rekey));
3245       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
3246           sizeof(session->DAA_tpmSpecific.DAA_count));
3247       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
3248       tpm_sha1_final(&sha1, scratch);
3249       tpm_sha1_init(&sha1);
3250       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
3251           sizeof(session->DAA_tpmSpecific.DAA_rekey));
3252       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
3253           sizeof(session->DAA_tpmSpecific.DAA_count));
3254       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
3255       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
3256       tpm_bn_init(f), tpm_bn_init(q);
3257       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
3258       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
3259         1, session->DAA_issuerSettings.DAA_generic_q);
3260       tpm_bn_mod(f, f, q);
3261       /* Set f0 = f mod 2^DAA_power0 (erase all but the lowest DAA_power0
3262        * bits of f) */
3263       tpm_bn_init(f0);
3264       tpm_bn_init(tmp);
3265       tpm_bn_ui_pow_ui(tmp, 2, DAA_power0);
3266       tpm_bn_mod(f0, f, tmp);
3267       /* Set s0 = r0 + (DAA_session->DAA_digest) * (f0) */
3268       tpm_bn_init(s0);
3269       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
3270         1, session->DAA_session.DAA_digest.digest);
3271       tpm_bn_mul(s0, tmp, f0);
3272       tpm_bn_add(s0, r0, s0);
3273       /* Set outputData = s0 */
3274       tpm_bn_export(scratch, &size, 1, s0);
3275       *outputSize = (uint32_t)size;
3276       tpm_bn_clear(r0), tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(f0);
3277       tpm_bn_clear(s0), tpm_bn_clear(tmp);
3278       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
3279         memcpy(*outputData, scratch, *outputSize);
3280       else {
3281         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3282         return TPM_NOSPACE;
3283       }
3284       /* Increment DAA_session->DAA_stage by 1 */
3285       session->DAA_session.DAA_stage++;
3286       /* Return TPM_SUCCESS */
3287       return TPM_SUCCESS;
3288     }
3289     case 12:
3290     {
3291       /* Verify that DAA_session->DAA_stage == 12. Return TPM_DAA_STAGE
3292        * and flush handle on mismatch */
3293       if (session->DAA_session.DAA_stage != 12) {
3294         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3295         return TPM_DAA_STAGE;
3296       }
3297       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
3298        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
3299        * on mismatch */
3300       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
3301         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3302         return TPM_DAA_ISSUER_SETTINGS;
3303       }
3304       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
3305        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
3306       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
3307         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3308         return TPM_DAA_TPM_SETTINGS;
3309       }
3310       /* Obtain DAA_SIZE_r1 bits from MGF1("r1",
3311        * DAA_session->DAA_contextSeed), and label them r1 */
3312       memset(scratch, 0, sizeof(scratch));
3313       memcpy(mgf1_seed, "r1", 2);
3314       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
3315         sizeof(TPM_NONCE));
3316       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r1);
3317       tpm_bn_init(r1);
3318       tpm_bn_import(r1, DAA_SIZE_r1, 1, scratch);
3319       /* Set f = SHA1(DAA_tpmSpecific->DAA_rekey ||
3320        * DAA_tpmSpecific->DAA_count || 0 ) ||
3321        * SHA1(DAA_tpmSpecific->DAA_rekey || DAA_tpmSpecific->DAA_count ||
3322        * 1 ) mod DAA_issuerSettings->DAA_generic_q */
3323       tpm_sha1_init(&sha1);
3324       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
3325           sizeof(session->DAA_tpmSpecific.DAA_rekey));
3326       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
3327           sizeof(session->DAA_tpmSpecific.DAA_count));
3328       tpm_sha1_update(&sha1, DAA_LABEL_00, 1);
3329       tpm_sha1_final(&sha1, scratch);
3330       tpm_sha1_init(&sha1);
3331       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
3332           sizeof(session->DAA_tpmSpecific.DAA_rekey));
3333       tpm_sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
3334           sizeof(session->DAA_tpmSpecific.DAA_count));
3335       tpm_sha1_update(&sha1, DAA_LABEL_01, 1);
3336       tpm_sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
3337       tpm_bn_init(f), tpm_bn_init(q);
3338       tpm_bn_import(f, 2 * SHA1_DIGEST_LENGTH, 1, scratch);
3339       tpm_bn_import(q, sizeof(session->DAA_issuerSettings.DAA_generic_q),
3340         1, session->DAA_issuerSettings.DAA_generic_q);
3341       tpm_bn_mod(f, f, q);
3342       /* Shift f right by DAA_power0 bits (discard the lowest DAA_power0
3343        * bits) and label the result f1 */
3344       tpm_bn_init(f1);
3345       tpm_bn_fdiv_q_2exp(f1, f, DAA_power0);
3346       /* Set s1 = r1 + (DAA_session->DAA_digest) * (f1) */
3347       tpm_bn_init(s1);
3348       tpm_bn_init(tmp);
3349       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
3350         1, session->DAA_session.DAA_digest.digest);
3351       tpm_bn_mul(s1, tmp, f1);
3352       tpm_bn_add(s1, r1, s1);
3353       /* Set outputData = s1 */
3354       tpm_bn_export(scratch, &size, 1, s1);
3355       *outputSize = (uint32_t)size;
3356       tpm_bn_clear(r1), tpm_bn_clear(f), tpm_bn_clear(q), tpm_bn_clear(f1);
3357       tpm_bn_clear(s1), tpm_bn_clear(tmp);
3358       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
3359         memcpy(*outputData, scratch, *outputSize);
3360       else {
3361         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3362         return TPM_NOSPACE;
3363       }
3364       /* Increment DAA_session->DAA_stage by 1 */
3365       session->DAA_session.DAA_stage++;
3366       /* Return TPM_SUCCESS */
3367       return TPM_SUCCESS;
3368     }
3369     case 13:
3370     {
3371       BYTE *DAA_private_v0 = NULL;
3372 
3373       /* Verify that DAA_session->DAA_stage == 13. Return TPM_DAA_STAGE
3374        * and flush handle on mismatch */
3375       if (session->DAA_session.DAA_stage != 13) {
3376         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3377         return TPM_DAA_STAGE;
3378       }
3379       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
3380        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
3381        * on mismatch */
3382       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
3383         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3384         return TPM_DAA_ISSUER_SETTINGS;
3385       }
3386       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
3387        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
3388       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
3389         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3390         return TPM_DAA_TPM_SETTINGS;
3391       }
3392       /* Set DAA_private_v0 = unwrap(inputData0) */
3393       ptr = inputData0, len = inputSize0;
3394       if (tpm_unmarshal_TPM_DAA_BLOB(&ptr, &len, &blob) || (len != 0)) {
3395         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3396         return TPM_DAA_INPUT_DATA0;
3397       }
3398       sensitive.internalData = scratch;
3399       if (decrypt_daa(blob.additionalData, blob.additionalSize,
3400         blob.sensitiveData, blob.sensitiveSize, &sensitive, &buf)) {
3401           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3402           return TPM_DECRYPT_ERROR;
3403       }
3404       if (compute_daa_digest(&blob, &digest) ||
3405         memcmp(&digest, &blob.blobIntegrity, sizeof(TPM_DIGEST))) {
3406           tpm_free(buf);
3407           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3408           return TPM_DAA_INPUT_DATA0;
3409       }
3410       if ((blob.resourceType != TPM_RT_DAA_V0) ||
3411         (sensitive.tag != TPM_TAG_DAA_SENSITIVE ||
3412         (sensitive.internalSize == 0) ||
3413         (sensitive.internalSize > DAA_SIZE_v0))) {
3414           tpm_free(buf);
3415           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3416           return TPM_DAA_INPUT_DATA0;
3417       }
3418       if ((DAA_private_v0 = tpm_malloc(DAA_SIZE_v0)) == NULL) {
3419         tpm_free(buf);
3420         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3421         return TPM_NOSPACE;
3422       }
3423       memcpy(DAA_private_v0, sensitive.internalData, sensitive.internalSize);
3424       tpm_free(buf);
3425       /* Verify that SHA-1(DAA_private_v0) == DAA_tpmSpecific->DAA_digest_v0
3426        * and return error TPM_DAA_INPUT_DATA0 on mismatch */
3427       tpm_sha1_init(&sha1);
3428       tpm_sha1_update(&sha1, DAA_private_v0, sensitive.internalSize);
3429       tpm_sha1_final(&sha1, (BYTE*) &digest);
3430       if (memcmp(&digest, &session->DAA_tpmSpecific.DAA_digest_v0,
3431         sizeof(TPM_DIGEST))) {
3432           tpm_free(DAA_private_v0);
3433           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3434           return TPM_DAA_INPUT_DATA0;
3435       }
3436       /* Obtain DAA_SIZE_r2 bits from MGF1("r2",
3437        * DAA_session->DAA_contextSeed), and label them r2 */
3438       memset(scratch, 0, sizeof(scratch));
3439       memcpy(mgf1_seed, "r2", 2);
3440       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
3441         sizeof(TPM_NONCE));
3442       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r2);
3443       tpm_bn_init(r2);
3444       tpm_bn_import(r2, DAA_SIZE_r2, 1, scratch);
3445       /* Set s2 = r2 + (DAA_session->DAA_digest) *
3446        * (DAA_private_v0) mod 2^DAA_power1
3447        * (Erase all but the lowest DAA_power1 bits of s2) */
3448       tpm_bn_init(s2);
3449       tpm_bn_import(s2, sensitive.internalSize, 1, DAA_private_v0);
3450       tpm_free(DAA_private_v0);
3451       tpm_bn_init(tmp);
3452       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
3453         1, session->DAA_session.DAA_digest.digest);
3454       tpm_bn_mul(s2, tmp, s2);
3455       tpm_bn_add(s2, r2, s2);
3456       tpm_bn_ui_pow_ui(tmp, 2, DAA_power1);
3457       tpm_bn_mod(s2, s2, tmp);
3458       /* Set DAA_session->DAA_scratch = s2 */
3459       memset(session->DAA_session.DAA_scratch, 0,
3460         sizeof(session->DAA_session.DAA_scratch));
3461       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, s2);
3462       /* Set outputData = s2 */
3463       tpm_bn_export(scratch, &size, 1, s2);
3464       *outputSize = (uint32_t)size;
3465       tpm_bn_clear(r2), tpm_bn_clear(s2), tpm_bn_clear(tmp);
3466       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
3467         memcpy(*outputData, scratch, *outputSize);
3468       else {
3469         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3470         return TPM_NOSPACE;
3471       }
3472       /* Increment DAA_session->DAA_stage by 1 */
3473       session->DAA_session.DAA_stage++;
3474       /* Return TPM_SUCCESS */
3475       return TPM_SUCCESS;
3476     }
3477     case 14:
3478     {
3479       BYTE *DAA_private_v0 = NULL;
3480 
3481       /* Verify that DAA_session->DAA_stage == 14. Return TPM_DAA_STAGE
3482        * and flush handle on mismatch */
3483       if (session->DAA_session.DAA_stage != 14) {
3484         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3485         return TPM_DAA_STAGE;
3486       }
3487       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
3488        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
3489        * on mismatch */
3490       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
3491         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3492         return TPM_DAA_ISSUER_SETTINGS;
3493       }
3494       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
3495        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
3496       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
3497         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3498         return TPM_DAA_TPM_SETTINGS;
3499       }
3500       /* Set DAA_private_v0 = unwrap(inputData0) */
3501       ptr = inputData0, len = inputSize0;
3502       if (tpm_unmarshal_TPM_DAA_BLOB(&ptr, &len, &blob) || (len != 0)) {
3503         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3504         return TPM_DAA_INPUT_DATA0;
3505       }
3506       sensitive.internalData = scratch;
3507       if (decrypt_daa(blob.additionalData, blob.additionalSize,
3508         blob.sensitiveData, blob.sensitiveSize, &sensitive, &buf)) {
3509           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3510           return TPM_DECRYPT_ERROR;
3511       }
3512       if (compute_daa_digest(&blob, &digest) ||
3513         memcmp(&digest, &blob.blobIntegrity, sizeof(TPM_DIGEST))) {
3514           tpm_free(buf);
3515           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3516           return TPM_DAA_INPUT_DATA0;
3517       }
3518       if ((blob.resourceType != TPM_RT_DAA_V0) ||
3519         (sensitive.tag != TPM_TAG_DAA_SENSITIVE ||
3520         (sensitive.internalSize == 0) ||
3521         (sensitive.internalSize > DAA_SIZE_v0))) {
3522           tpm_free(buf);
3523           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3524           return TPM_DAA_INPUT_DATA0;
3525       }
3526       if ((DAA_private_v0 = tpm_malloc(DAA_SIZE_v0)) == NULL) {
3527         tpm_free(buf);
3528         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3529         return TPM_NOSPACE;
3530       }
3531       memcpy(DAA_private_v0, sensitive.internalData, sensitive.internalSize);
3532       tpm_free(buf);
3533       /* Verify that SHA-1(DAA_private_v0) == DAA_tpmSpecific->DAA_digest_v0
3534        * and return error TPM_DAA_INPUT_DATA0 on mismatch */
3535       tpm_sha1_init(&sha1);
3536       tpm_sha1_update(&sha1, DAA_private_v0, sensitive.internalSize);
3537       tpm_sha1_final(&sha1, (BYTE*) &digest);
3538       if (memcmp(&digest, &session->DAA_tpmSpecific.DAA_digest_v0,
3539         sizeof(TPM_DIGEST))) {
3540           tpm_free(DAA_private_v0);
3541           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3542           return TPM_DAA_INPUT_DATA0;
3543       }
3544       /* Obtain DAA_SIZE_r2 bits from MGF1("r2",
3545        * DAA_session->DAA_contextSeed), and label them r2 */
3546       memset(scratch, 0, sizeof(scratch));
3547       memcpy(mgf1_seed, "r2", 2);
3548       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
3549         sizeof(TPM_NONCE));
3550       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r2);
3551       tpm_bn_init(r2);
3552       tpm_bn_import(r2, DAA_SIZE_r2, 1, scratch);
3553       /* Set s12 = r2 + (DAA_session->DAA_digest) * (DAA_private_v0). */
3554       tpm_bn_init(s12);
3555       tpm_bn_import(s12, sensitive.internalSize, 1, DAA_private_v0);
3556       tpm_free(DAA_private_v0);
3557       tpm_bn_init(tmp);
3558       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
3559         1, session->DAA_session.DAA_digest.digest);
3560       tpm_bn_mul(s12, tmp, s12);
3561       tpm_bn_add(s12, r2, s12);
3562       /* Shift s12 right by DAA_power1 bits (erase the lowest DAA_power1
3563        * bits). */
3564       tpm_bn_fdiv_q_2exp(s12, s12, DAA_power1);
3565       /* Set DAA_session->DAA_scratch = s12 */
3566       memset(session->DAA_session.DAA_scratch, 0,
3567         sizeof(session->DAA_session.DAA_scratch));
3568       tpm_bn_export(session->DAA_session.DAA_scratch, NULL, -1, s12);
3569       tpm_bn_clear(r2), tpm_bn_clear(s12), tpm_bn_clear(tmp);
3570       /* Set outputData = NULL */
3571       *outputSize = 0, *outputData = NULL;
3572       /* Increment DAA_session->DAA_stage by 1 */
3573       session->DAA_session.DAA_stage++;
3574       /* Return TPM_SUCCESS */
3575       return TPM_SUCCESS;
3576     }
3577     case 15:
3578     {
3579       BYTE *DAA_private_v1 = NULL;
3580 
3581       /* Verify that DAA_session->DAA_stage == 15. Return TPM_DAA_STAGE
3582        * and flush handle on mismatch */
3583       if (session->DAA_session.DAA_stage != 15) {
3584         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3585         return TPM_DAA_STAGE;
3586       }
3587       /* Verify that DAA_tpmSpecific->DAA_digestIssuer ==
3588        * SHA-1(DAA_issuerSettings) and return error TPM_DAA_ISSUER_SETTINGS
3589        * on mismatch */
3590       if (tpm_daa_verify_digestIssuer(session, &sha1)) {
3591         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3592         return TPM_DAA_ISSUER_SETTINGS;
3593       }
3594       /* Verify that DAA_session->DAA_digestContext == SHA-1(DAA_tpmSpecific)
3595        * and return error TPM_DAA_TPM_SETTINGS on mismatch */
3596       if (tpm_daa_verify_digestContext_sign(session, &sha1)) {
3597         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3598         return TPM_DAA_TPM_SETTINGS;
3599       }
3600       /* Set DAA_private_v1 = unwrap(inputData0) */
3601       ptr = inputData0, len = inputSize0;
3602       if (tpm_unmarshal_TPM_DAA_BLOB(&ptr, &len, &blob) || (len != 0)) {
3603         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3604         return TPM_DAA_INPUT_DATA0;
3605       }
3606       sensitive.internalData = scratch;
3607       if (decrypt_daa(blob.additionalData, blob.additionalSize,
3608         blob.sensitiveData, blob.sensitiveSize, &sensitive, &buf)) {
3609           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3610           return TPM_DECRYPT_ERROR;
3611       }
3612       if (compute_daa_digest(&blob, &digest) ||
3613         memcmp(&digest, &blob.blobIntegrity, sizeof(TPM_DIGEST))) {
3614           tpm_free(buf);
3615           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3616           return TPM_DAA_INPUT_DATA0;
3617       }
3618       if ((blob.resourceType != TPM_RT_DAA_V1) ||
3619         (sensitive.tag != TPM_TAG_DAA_SENSITIVE ||
3620         (sensitive.internalSize == 0) ||
3621         (sensitive.internalSize > DAA_SIZE_v1))) {
3622           tpm_free(buf);
3623           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3624           return TPM_DAA_INPUT_DATA0;
3625       }
3626       if ((DAA_private_v1 = tpm_malloc(DAA_SIZE_v1)) == NULL) {
3627         tpm_free(buf);
3628         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3629         return TPM_NOSPACE;
3630       }
3631       memcpy(DAA_private_v1, sensitive.internalData, sensitive.internalSize);
3632       tpm_free(buf);
3633       /* Verify that SHA-1(DAA_private_v1) == DAA_tpmSpecific->DAA_digest_v1
3634        * and return error TPM_DAA_INPUT_DATA0 on mismatch */
3635       tpm_sha1_init(&sha1);
3636       tpm_sha1_update(&sha1, DAA_private_v1, sensitive.internalSize);
3637       tpm_sha1_final(&sha1, (BYTE*) &digest);
3638       if (memcmp(&digest, &session->DAA_tpmSpecific.DAA_digest_v1,
3639         sizeof(TPM_DIGEST))) {
3640           tpm_free(DAA_private_v1);
3641           memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3642           return TPM_DAA_INPUT_DATA0;
3643       }
3644       /* Obtain DAA_SIZE_r4 bits from MGF1("r4",
3645        * DAA_session->DAA_contextSeed), and label them r4 */
3646       memset(scratch, 0, sizeof(scratch));
3647       memcpy(mgf1_seed, "r4", 2);
3648       memcpy(mgf1_seed + 2, session->DAA_session.DAA_contextSeed.nonce,
3649         sizeof(TPM_NONCE));
3650       tpm_rsa_mask_generation(mgf1_seed, sizeof(mgf1_seed), scratch, DAA_SIZE_r4);
3651       tpm_bn_init(r4);
3652       tpm_bn_import(r4, DAA_SIZE_r4, 1, scratch);
3653       /* Set s3 = r4 + (DAA_session->DAA_digest) * (DAA_private_v1) +
3654        * (DAA_session->DAA_scratch). */
3655       tpm_bn_init(s3);
3656       tpm_bn_import(s3, sensitive.internalSize, 1, DAA_private_v1);
3657       tpm_free(DAA_private_v1);
3658       tpm_bn_init(tmp);
3659       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_digest.digest),
3660         1, session->DAA_session.DAA_digest.digest);
3661       tpm_bn_mul(s3, tmp, s3);
3662       tpm_bn_add(s3, r4, s3);
3663       tpm_bn_import(tmp, sizeof(session->DAA_session.DAA_scratch),
3664         -1, session->DAA_session.DAA_scratch);
3665       tpm_bn_add(s3, s3, tmp);
3666       /* Set DAA_session->DAA_scratch = NULL */
3667       memset(session->DAA_session.DAA_scratch, 0,
3668         sizeof(session->DAA_session.DAA_scratch));
3669       /* Set outputData = s3 */
3670       tpm_bn_export(scratch, &size, 1, s3);
3671       *outputSize = (uint32_t)size;
3672       tpm_bn_clear(r4), tpm_bn_clear(s3), tpm_bn_clear(tmp);
3673       if ((*outputData = tpm_malloc(*outputSize)) != NULL)
3674         memcpy(*outputData, scratch, *outputSize);
3675       else {
3676         memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3677         return TPM_NOSPACE;
3678       }
3679       /* Terminate the DAA session and all resources assoociated with the
3680        * DAA sign session handle. */
3681       memset(session, 0, sizeof(TPM_DAA_SESSION_DATA));
3682       /* Return TPM_SUCCESS */
3683       return TPM_SUCCESS;
3684     }
3685     default:
3686       return TPM_DAA_STAGE;
3687   }
3688 }
3689