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