From 92cccad89d1c12b39165d5f0ed7ccd2d44965a1a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 23:41:43 +0200 Subject: Adding upstream version 0.9.2. Signed-off-by: Daniel Baumann --- src/tpm12/tpm_daa.c | 5729 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5729 insertions(+) create mode 100644 src/tpm12/tpm_daa.c (limited to 'src/tpm12/tpm_daa.c') diff --git a/src/tpm12/tpm_daa.c b/src/tpm12/tpm_daa.c new file mode 100644 index 0000000..7c0056e --- /dev/null +++ b/src/tpm12/tpm_daa.c @@ -0,0 +1,5729 @@ +/********************************************************************************/ +/* */ +/* DAA Handler */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: tpm_daa.c 4768 2017-07-28 13:19:28Z kgoldman $ */ +/* */ +/* (c) Copyright IBM Corporation 2006, 2010. */ +/* */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions are */ +/* met: */ +/* */ +/* Redistributions of source code must retain the above copyright notice, */ +/* this list of conditions and the following disclaimer. */ +/* */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the names of the IBM Corporation nor the names of its */ +/* contributors may be used to endorse or promote products derived from */ +/* this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ +/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ +/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ +/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ +/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ +/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/********************************************************************************/ + +#include +#include +#include + +#include "tpm_auth.h" +#include "tpm_crypto.h" +#include "tpm_cryptoh.h" +#include "tpm_debug.h" +#include "tpm_error.h" +#include "tpm_init.h" +#include "tpm_key.h" +#include "tpm_memory.h" +#include "tpm_nonce.h" +#include "tpm_process.h" +#include "tpm_sizedbuffer.h" + +#include "tpm_daa.h" + +/* + TPM_DAA_SESSION_DATA (the entire array) +*/ + +void TPM_DaaSessions_Init(TPM_DAA_SESSION_DATA *daaSessions) +{ + size_t i; + + printf(" TPM_DaaSessions_Init:\n"); + for (i = 0 ; i < TPM_MIN_DAA_SESSIONS ; i++) { + TPM_DaaSessionData_Init(&(daaSessions[i])); + } + return; +} + +/* TPM_DaaSessions_Load() reads a count of the number of stored sessions and then loads those + sessions. + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DaaSessions_Init() +*/ + +TPM_RESULT TPM_DaaSessions_Load(TPM_DAA_SESSION_DATA *daaSessions, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + size_t i; + uint32_t activeCount; + + printf(" TPM_DaaSessions_Load:\n"); + /* load active count */ + if (rc == 0) { + rc = TPM_Load32(&activeCount, stream, stream_size); + } + if (rc == 0) { + if (activeCount > TPM_MIN_DAA_SESSIONS) { + printf("TPM_DaaSessions_Load: Error (fatal) %u sessions, %u slots\n", + activeCount, TPM_MIN_DAA_SESSIONS); + rc = TPM_FAIL; + } + } + if (rc == 0) { + printf(" TPM_DaaSessions_Load: Loading %u sessions\n", activeCount); + } + /* load DAA sessions */ + for (i = 0 ; (rc == 0) && (i < activeCount) ; i++) { + rc = TPM_DaaSessionData_Load(&(daaSessions[i]), stream, stream_size); + } + return rc; +} + +/* TPM_DaaSessions_Store() stores a count of the active sessions, followed by the sessions. + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DaaSessions_Store(TPM_STORE_BUFFER *sbuffer, + TPM_DAA_SESSION_DATA *daaSessions) +{ + TPM_RESULT rc = 0; + size_t i; + uint32_t space; + uint32_t activeCount; + + /* store active count */ + if (rc == 0) { + TPM_DaaSessions_GetSpace(&space, daaSessions); + activeCount = TPM_MIN_DAA_SESSIONS - space; + printf(" TPM_DaaSessions_Store: Storing %u sessions\n", activeCount); + rc = TPM_Sbuffer_Append32(sbuffer, activeCount); + } + /* store DAA sessions */ + for (i = 0 ; (rc == 0) && (i < TPM_MIN_DAA_SESSIONS) ; i++) { + if ((daaSessions[i]).valid) { /* if the session is active */ + rc = TPM_DaaSessionData_Store(sbuffer, &(daaSessions[i])); + } + } + return rc; +} + +/* TPM_DaaSessions_Delete() terminates all loaded DAA sessions + +*/ + +void TPM_DaaSessions_Delete(TPM_DAA_SESSION_DATA *daaSessions) +{ + size_t i; + + printf(" TPM_DaaSessions_Delete:\n"); + for (i = 0 ; i < TPM_MIN_DAA_SESSIONS ; i++) { + TPM_DaaSessionData_Delete(&(daaSessions[i])); + } + return; +} + +/* TPM_DaaSessions_IsSpace() returns 'isSpace' TRUE if an entry is available, FALSE if not. + + If TRUE, 'index' holds the first free position. +*/ + +void TPM_DaaSessions_IsSpace(TPM_BOOL *isSpace, + uint32_t *index, + TPM_DAA_SESSION_DATA *daaSessions) +{ + printf(" TPM_DaaSessions_IsSpace:\n"); + for (*index = 0, *isSpace = FALSE ; *index < TPM_MIN_DAA_SESSIONS ; (*index)++) { + if (!((daaSessions[*index]).valid)) { + printf(" TPM_DaaSessions_IsSpace: Found space at %u\n", *index); + *isSpace = TRUE; + break; + } + } + return; +} + +/* TPM_DaaSessions_GetSpace() returns the number of unused daaHandle's. + +*/ + +void TPM_DaaSessions_GetSpace(uint32_t *space, + TPM_DAA_SESSION_DATA *daaSessions) +{ + uint32_t i; + + printf(" TPM_DaaSessions_GetSpace:\n"); + for (*space = 0 , i = 0 ; i < TPM_MIN_DAA_SESSIONS ; i++) { + if (!((daaSessions[i]).valid)) { + (*space)++; + } + } + return; +} + +/* TPM_DaaSessions_StoreHandles() stores + + - the number of loaded sessions + - a list of session handles +*/ + +TPM_RESULT TPM_DaaSessions_StoreHandles(TPM_STORE_BUFFER *sbuffer, + TPM_DAA_SESSION_DATA *daaSessions) +{ + TPM_RESULT rc = 0; + uint16_t i; + uint32_t space; + + printf(" TPM_DaaSessions_StoreHandles:\n"); + /* get the number of loaded handles */ + if (rc == 0) { + TPM_DaaSessions_GetSpace(&space, daaSessions); + /* store loaded handle count. Safe case because of TPM_MIN_DAA_SESSIONS value */ + rc = TPM_Sbuffer_Append16(sbuffer, (uint16_t)(TPM_MIN_DAA_SESSIONS - space)); + } + for (i = 0 ; (rc == 0) && (i < TPM_MIN_DAA_SESSIONS) ; i++) { + if ((daaSessions[i]).valid) { /* if the index is loaded */ + rc = TPM_Sbuffer_Append32(sbuffer, (daaSessions[i]).daaHandle); /* store it */ + } + } + return rc; +} + +/* TPM_DaaSessions_GetNewHandle() checks for space in the DAA sessions table. + + If there is space, it returns a TPM_DAA_SESSION_DATA entry in 'tpm_daa_session_data' and its + handle in 'daaHandle'. The entry is marked 'valid'. + + If *daaHandle non-zero, the suggested value is tried first. + + Returns TPM_RESOURCES if there is no space in the sessions table. +*/ + +TPM_RESULT TPM_DaaSessions_GetNewHandle(TPM_DAA_SESSION_DATA **tpm_daa_session_data, /* entry */ + TPM_HANDLE *daaHandle, + TPM_BOOL *daaHandleValid, + TPM_DAA_SESSION_DATA *daaSessions) /* array */ +{ + TPM_RESULT rc = 0; + uint32_t index; + TPM_BOOL isSpace; + + printf(" TPM_DaaSessions_GetNewHandle:\n"); + *daaHandle = FALSE; + /* is there an empty entry, get the location index */ + if (rc == 0) { + TPM_DaaSessions_IsSpace(&isSpace, /* TRUE if space available */ + &index, /* if space available, index into array */ + daaSessions); /* array */ + if (!isSpace) { + printf("TPM_DaaSessions_GetNewHandle: Error, no space in daaSessions table\n"); + rc = TPM_RESOURCES; + } + } + if (rc == 0) { + rc = TPM_Handle_GenerateHandle(daaHandle, /* I/O, pointer to handle */ + daaSessions, /* handle array */ + FALSE, /* keepHandle */ + FALSE, /* isKeyHandle */ + (TPM_GETENTRY_FUNCTION_T)TPM_DaaSessions_GetEntry); + } + if (rc == 0) { + printf(" TPM_DaaSessions_GetNewHandle: Assigned handle %08x\n", *daaHandle); + *tpm_daa_session_data = &(daaSessions[index]); + TPM_DaaSessionData_Init(*tpm_daa_session_data); /* should be redundant since + terminate should have done + this */ + (*tpm_daa_session_data)->daaHandle = *daaHandle; + (*tpm_daa_session_data)->valid = TRUE; + *daaHandleValid = TRUE; + } + return rc; +} + +/* TPM_DaaSessions_GetEntry() searches all entries for the entry matching the handle, and + returns the TPM_DAA_SESSION_DATA entry associated with the handle. + + Returns + 0 for success + TPM_BAD_HANDLE if the handle is not found +*/ + +TPM_RESULT TPM_DaaSessions_GetEntry(TPM_DAA_SESSION_DATA **tpm_daa_session_data, /* session for + daaHandle */ + TPM_DAA_SESSION_DATA *daaSessions, /* points to first session in + array */ + TPM_HANDLE daaHandle) /* input */ +{ + TPM_RESULT rc = 0; + size_t i; + TPM_BOOL found; + + printf(" TPM_DaaSessions_GetEntry: daaHandle %08x\n", daaHandle); + for (i = 0, found = FALSE ; (i < TPM_MIN_DAA_SESSIONS) && !found ; i++) { + if ((daaSessions[i].valid) && + (daaSessions[i].daaHandle == daaHandle)) { /* found */ + found = TRUE; + *tpm_daa_session_data = &(daaSessions[i]); + } + } + if (!found) { + printf(" TPM_DaaSessions_GetEntry: session handle %08x not found\n", + daaHandle); + rc = TPM_BAD_HANDLE; + } + return rc; +} + +/* TPM_DaaSessions_AddEntry() adds an TPM_DAA_SESSION_DATA object to the list. + + If *tpm_handle == 0, a value is assigned. If *tpm_handle != 0, that value is used if it it not + currently in use. + + The handle is returned in tpm_handle. +*/ + +TPM_RESULT TPM_DaaSessions_AddEntry(TPM_HANDLE *tpm_handle, /* i/o */ + TPM_BOOL keepHandle, /* input */ + TPM_DAA_SESSION_DATA *daaSessions, /* input */ + TPM_DAA_SESSION_DATA *tpm_daa_session_data) /* input */ +{ + TPM_RESULT rc = 0; + uint32_t index; + TPM_BOOL isSpace; + + printf(" TPM_DaaSessions_AddEntry:\n"); + /* check for valid TPM_DAA_SESSION_DATA */ + if (rc == 0) { + if (tpm_daa_session_data == NULL) { /* NOTE: should never occur */ + printf("TPM_DaaSessions_AddEntry: Error (fatal), NULL TPM_DAA_SESSION_DATA\n"); + rc = TPM_FAIL; + } + } + /* is there an empty entry, get the location index */ + if (rc == 0) { + TPM_DaaSessions_IsSpace(&isSpace, &index, daaSessions); + if (!isSpace) { + printf("TPM_DaaSessions_AddEntry: Error, session entries full\n"); + rc = TPM_RESOURCES; + } + } + if (rc == 0) { + rc = TPM_Handle_GenerateHandle(tpm_handle, /* I/O */ + daaSessions, /* handle array */ + keepHandle, /* keepHandle */ + FALSE, /* isKeyHandle */ + (TPM_GETENTRY_FUNCTION_T)TPM_DaaSessions_GetEntry); + } + if (rc == 0) { + TPM_DaaSessionData_Copy(&(daaSessions[index]), *tpm_handle, tpm_daa_session_data); + daaSessions[index].valid = TRUE; + printf(" TPM_DaaSessions_AddEntry: Index %u handle %08x\n", + index, daaSessions[index].daaHandle); + } + return rc; +} + +/* TPM_DaaSessions_TerminateHandle() terminates the session associated with 'daaHandle'. + +*/ + +TPM_RESULT TPM_DaaSessions_TerminateHandle(TPM_DAA_SESSION_DATA *daaSessions, + TPM_HANDLE daaHandle) +{ + TPM_RESULT rc = 0; + TPM_DAA_SESSION_DATA *tpm_daa_session_data; + + printf(" TPM_DaaSessions_TerminateHandle: daaHandle %08x\n", daaHandle); + /* get the TPM_DAA_SESSION_DATA associated with the TPM_HANDLE */ + if (rc == 0) { + rc = TPM_DaaSessions_GetEntry(&tpm_daa_session_data, /* returns entry in array */ + daaSessions, /* array */ + daaHandle); + } + /* invalidate the valid handle */ + if (rc == 0) { + TPM_DaaSessionData_Delete(tpm_daa_session_data); + } + return rc; +} + +/* + TPM_DAA_SESSION_DATA (one element of the array) +*/ + +/* TPM_DaaSessionData_Init() initializes the DAA session. + + sets members to default values + sets all pointers to NULL and sizes to 0 + always succeeds - no return code +*/ + +void TPM_DaaSessionData_Init(TPM_DAA_SESSION_DATA *tpm_daa_session_data) +{ + printf(" TPM_DaaSessionData_Init:\n"); + TPM_DAAIssuer_Init(&(tpm_daa_session_data->DAA_issuerSettings)); + TPM_DAATpm_Init(&(tpm_daa_session_data->DAA_tpmSpecific)); + TPM_DAAContext_Init(&(tpm_daa_session_data->DAA_session)); + TPM_DAAJoindata_Init(&(tpm_daa_session_data->DAA_joinSession)); + tpm_daa_session_data->daaHandle = 0; + tpm_daa_session_data->valid = FALSE; + return; +} + +/* TPM_DaaSessionData_Load() + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DaaSessionData_Init() + After use, call TPM_DaaSessionData_Delete() to free memory +*/ + +TPM_RESULT TPM_DaaSessionData_Load(TPM_DAA_SESSION_DATA *tpm_daa_session_data, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DaaSessionData_Load:\n"); + /* load DAA_issuerSettings */ + if (rc == 0) { + rc = TPM_DAAIssuer_Load(&(tpm_daa_session_data->DAA_issuerSettings), stream, stream_size); + } + /* load DAA_tpmSpecific */ + if (rc == 0) { + rc = TPM_DAATpm_Load(&(tpm_daa_session_data->DAA_tpmSpecific), stream, stream_size); + } + /* load DAA_session */ + if (rc == 0) { + rc = TPM_DAAContext_Load(&(tpm_daa_session_data->DAA_session),stream, stream_size); + } + /* load DAA_joinSession */ + if (rc == 0) { + rc = TPM_DAAJoindata_Load(&(tpm_daa_session_data->DAA_joinSession), stream, stream_size); + } + /* load daaHandle */ + if (rc == 0) { + rc = TPM_Load32(&(tpm_daa_session_data->daaHandle), stream, stream_size); + } + /* set valid */ + if (rc == 0) { + tpm_daa_session_data->valid = TRUE; + } + return rc; +} + +/* TPM_DaaSessionData_Store() + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DaaSessionData_Store(TPM_STORE_BUFFER *sbuffer, + const TPM_DAA_SESSION_DATA *tpm_daa_session_data) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DaaSessionData_Store:\n"); + /* store DAA_issuerSettings */ + if (rc == 0) { + rc = TPM_DAAIssuer_Store(sbuffer, &(tpm_daa_session_data->DAA_issuerSettings)); + } + /* store DAA_tpmSpecific */ + if (rc == 0) { + rc = TPM_DAATpm_Store(sbuffer, &(tpm_daa_session_data->DAA_tpmSpecific)); + } + /* store DAA_session */ + if (rc == 0) { + rc = TPM_DAAContext_Store(sbuffer, &(tpm_daa_session_data->DAA_session)); + } + /* store DAA_joinSession */ + if (rc == 0) { + rc = TPM_DAAJoindata_Store(sbuffer, &(tpm_daa_session_data->DAA_joinSession)); + } + /* store daaHandle */ + if (rc == 0) { + rc = TPM_Sbuffer_Append32(sbuffer, tpm_daa_session_data->daaHandle); + } + return rc; +} + +/* TPM_DaaSessionData_Delete() terminates the DAA session. + + No-OP if the parameter is NULL, else: + frees memory allocated for the object + sets pointers to NULL + calls TPM_DaaSessionData_Init to set members back to default values + The object itself is not freed +*/ + +void TPM_DaaSessionData_Delete(TPM_DAA_SESSION_DATA *tpm_daa_session_data) +{ + printf(" TPM_DaaSessionData_Delete:\n"); + if (tpm_daa_session_data != NULL) { + TPM_DAAIssuer_Delete(&(tpm_daa_session_data->DAA_issuerSettings)); + TPM_DAATpm_Delete(&(tpm_daa_session_data->DAA_tpmSpecific)); + TPM_DAAContext_Delete(&(tpm_daa_session_data->DAA_session)); + TPM_DAAJoindata_Delete(&(tpm_daa_session_data->DAA_joinSession)); + TPM_DaaSessionData_Init(tpm_daa_session_data); + } + return; +} + +/* TPM_DaaSessionData_Copy() copies the source to the destination. The source handle is ignored, + since it might already be used. +*/ + +void TPM_DaaSessionData_Copy(TPM_DAA_SESSION_DATA *dest_daa_session_data, + TPM_HANDLE tpm_handle, + TPM_DAA_SESSION_DATA *src_daa_session_data) +{ + dest_daa_session_data->daaHandle = tpm_handle; + TPM_DAAIssuer_Copy(&(dest_daa_session_data->DAA_issuerSettings), + &(src_daa_session_data->DAA_issuerSettings)); + TPM_DAATpm_Copy(&(dest_daa_session_data->DAA_tpmSpecific), + &(src_daa_session_data->DAA_tpmSpecific)); + TPM_DAAContext_Copy(&(dest_daa_session_data->DAA_session), + &(src_daa_session_data->DAA_session)); + TPM_DAAJoindata_Copy(&(dest_daa_session_data->DAA_joinSession), + &(src_daa_session_data->DAA_joinSession)); + dest_daa_session_data->valid= src_daa_session_data->valid; + return; +} + +/* TPM_DaaSessionData_CheckStage() verifies that the actual command processing stage is consistent + with the stage expected by the TPM state. +*/ + +TPM_RESULT TPM_DaaSessionData_CheckStage(TPM_DAA_SESSION_DATA *tpm_daa_session_data, + BYTE stage) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DaaSessionData_CheckStage:\n"); + if (tpm_daa_session_data->DAA_session.DAA_stage != stage) { + printf("TPM_DaaSessionData_CheckStage: Error, stage expected %u actual %u\n", + tpm_daa_session_data->DAA_session.DAA_stage, stage); + rc = TPM_DAA_STAGE; + } + return rc; +} + +/* + TPM_DAA_ISSUER +*/ + +/* TPM_DAAIssuer_Init() + + sets members to default values + sets all pointers to NULL and sizes to 0 + always succeeds - no return code +*/ + +void TPM_DAAIssuer_Init(TPM_DAA_ISSUER *tpm_daa_issuer) +{ + printf(" TPM_DAAIssuer_Init:\n"); + + TPM_Digest_Init(tpm_daa_issuer->DAA_digest_R0); + TPM_Digest_Init(tpm_daa_issuer->DAA_digest_R1); + TPM_Digest_Init(tpm_daa_issuer->DAA_digest_S0); + TPM_Digest_Init(tpm_daa_issuer->DAA_digest_S1); + TPM_Digest_Init(tpm_daa_issuer->DAA_digest_n); + TPM_Digest_Init(tpm_daa_issuer->DAA_digest_gamma); + memset(tpm_daa_issuer->DAA_generic_q, 0, sizeof(tpm_daa_issuer->DAA_generic_q)); + return; +} + +/* TPM_DAAIssuer_Load() + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DAAIssuer_Init() + After use, call TPM_DAAIssuer_Delete() to free memory +*/ + +TPM_RESULT TPM_DAAIssuer_Load(TPM_DAA_ISSUER *tpm_daa_issuer, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAAIssuer_Load:\n"); + /* check tag */ + if (rc == 0) { + rc = TPM_CheckTag(TPM_TAG_DAA_ISSUER, stream, stream_size); + } + /* load DAA_digest_R0 */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_issuer->DAA_digest_R0, stream, stream_size); + } + /* load DAA_digest_R1 */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_issuer->DAA_digest_R1, stream, stream_size); + } + /* load DAA_digest_S0 */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_issuer->DAA_digest_S0, stream, stream_size); + } + /* load DAA_digest_S1 */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_issuer->DAA_digest_S1, stream, stream_size); + } + /* load DAA_digest_n */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_issuer->DAA_digest_n, stream, stream_size); + } + /* load DAA_digest_gamma */ + if (rc == 0) { + rc = TPM_Digest_Load (tpm_daa_issuer->DAA_digest_gamma, stream, stream_size); + } + /* load DAA_generic_q */ + if (rc == 0) { + rc = TPM_Loadn(tpm_daa_issuer->DAA_generic_q, sizeof(tpm_daa_issuer->DAA_generic_q), + stream, stream_size); + } + return rc; +} + +/* TPM_DAAIssuer_Store() + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DAAIssuer_Store(TPM_STORE_BUFFER *sbuffer, + const TPM_DAA_ISSUER *tpm_daa_issuer) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAAIssuer_Store:\n"); + /* store tag */ + if (rc == 0) { + rc = TPM_Sbuffer_Append16(sbuffer, TPM_TAG_DAA_ISSUER); + } + /* store DAA_digest_R0 */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_issuer->DAA_digest_R0); + } + /* store DAA_digest_R1 */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_issuer->DAA_digest_R1); + } + /* store DAA_digest_S0 */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_issuer->DAA_digest_S0); + } + /* store DAA_digest_S1 */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_issuer->DAA_digest_S1); + } + /* store DAA_digest_n */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_issuer->DAA_digest_n); + } + /* store DAA_digest_gamma */ + if (rc == 0) { + rc = TPM_Digest_Store (sbuffer, tpm_daa_issuer->DAA_digest_gamma); + } + /* store DAA_generic_q */ + if (rc == 0) { + rc = TPM_Sbuffer_Append(sbuffer, + tpm_daa_issuer->DAA_generic_q, + sizeof(tpm_daa_issuer->DAA_generic_q)); + } + return rc; +} + +/* TPM_DAAIssuer_Delete() + + No-OP if the parameter is NULL, else: + frees memory allocated for the object + sets pointers to NULL + calls TPM_DAAIssuer_Init to set members back to default values + The object itself is not freed +*/ + +void TPM_DAAIssuer_Delete(TPM_DAA_ISSUER *tpm_daa_issuer) +{ + printf(" TPM_DAAIssuer_Delete:\n"); + if (tpm_daa_issuer != NULL) { + TPM_DAAIssuer_Init(tpm_daa_issuer); + } + return; +} + +/* TPM_DAAIssuer_Copy() copies the source to the destination + +*/ + +void TPM_DAAIssuer_Copy(TPM_DAA_ISSUER *dest_daa_issuer, + TPM_DAA_ISSUER *src_daa_issuer) +{ + printf(" TPM_DAAIssuer_Copy:\n"); + + TPM_Digest_Copy(dest_daa_issuer->DAA_digest_R0, src_daa_issuer->DAA_digest_R0); + TPM_Digest_Copy(dest_daa_issuer->DAA_digest_R1, src_daa_issuer->DAA_digest_R1); + TPM_Digest_Copy(dest_daa_issuer->DAA_digest_S0, src_daa_issuer->DAA_digest_S0); + TPM_Digest_Copy(dest_daa_issuer->DAA_digest_S1, src_daa_issuer->DAA_digest_S1); + TPM_Digest_Copy(dest_daa_issuer->DAA_digest_n, src_daa_issuer->DAA_digest_n); + TPM_Digest_Copy(dest_daa_issuer->DAA_digest_gamma, src_daa_issuer->DAA_digest_gamma); + memcpy(dest_daa_issuer->DAA_generic_q, src_daa_issuer->DAA_generic_q, + sizeof(src_daa_issuer->DAA_generic_q)); + return; +} + +/* + TPM_DAA_TPM +*/ + +/* TPM_DAATpm_Init() + + sets members to default values + sets all pointers to NULL and sizes to 0 + always succeeds - no return code +*/ + +void TPM_DAATpm_Init(TPM_DAA_TPM *tpm_daa_tpm) +{ + printf(" TPM_DAATpm_Init:\n"); + TPM_Digest_Init(tpm_daa_tpm->DAA_digestIssuer); + TPM_Digest_Init(tpm_daa_tpm->DAA_digest_v0); + TPM_Digest_Init(tpm_daa_tpm->DAA_digest_v1); + TPM_Digest_Init(tpm_daa_tpm->DAA_rekey); + tpm_daa_tpm->DAA_count = 0; + return; +} + +/* TPM_DAATpm_Load() + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DAATpm_Init() + After use, call TPM_DAATpm_Delete() to free memory +*/ + +TPM_RESULT TPM_DAATpm_Load(TPM_DAA_TPM *tpm_daa_tpm, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAATpm_Load:\n"); + /* check tag */ + if (rc == 0) { + rc = TPM_CheckTag(TPM_TAG_DAA_TPM, stream, stream_size); + } + /* load DAA_digestIssuer */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_tpm->DAA_digestIssuer, stream, stream_size); + } + /* load DAA_digest_v0 */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_tpm->DAA_digest_v0, stream, stream_size); + } + /* load DAA_digest_v1 */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_tpm->DAA_digest_v1, stream, stream_size); + } + /* load DAA_rekey */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_tpm->DAA_rekey, stream, stream_size); + } + /* load DAA_count */ + if (rc == 0) { + rc = TPM_Load32(&(tpm_daa_tpm->DAA_count), stream, stream_size); + } + return rc; +} + +/* TPM_DAATpm_Store() + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DAATpm_Store(TPM_STORE_BUFFER *sbuffer, + const TPM_DAA_TPM *tpm_daa_tpm) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAATpm_Store:\n"); + /* store tag */ + if (rc == 0) { + rc = TPM_Sbuffer_Append16(sbuffer, TPM_TAG_DAA_TPM); + } + /* store DAA_digestIssuer */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_tpm->DAA_digestIssuer); + } + /* store DAA_digest_v0 */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_tpm->DAA_digest_v0); + } + /* store DAA_digest_v1 */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_tpm->DAA_digest_v1); + } + /* store DAA_rekey */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_tpm->DAA_rekey); + } + /* store DAA_count */ + if (rc == 0) { + rc = TPM_Sbuffer_Append32(sbuffer, tpm_daa_tpm->DAA_count); + } + return rc; +} + +/* TPM_DAATpm_Delete() + + No-OP if the parameter is NULL, else: + frees memory allocated for the object + sets pointers to NULL + calls TPM_DAATpm_Init to set members back to default values + The object itself is not freed +*/ + +void TPM_DAATpm_Delete(TPM_DAA_TPM *tpm_daa_tpm) +{ + printf(" TPM_DAATpm_Delete:\n"); + if (tpm_daa_tpm != NULL) { + TPM_DAATpm_Init(tpm_daa_tpm); + } + return; +} + +/* TPM_DAATpm_Copy() copies the source to the destination + +*/ + +void TPM_DAATpm_Copy(TPM_DAA_TPM *dest_daa_tpm, TPM_DAA_TPM *src_daa_tpm) +{ + printf(" TPM_DAATpm_Copy:\n"); + TPM_Digest_Copy(dest_daa_tpm->DAA_digestIssuer, src_daa_tpm->DAA_digestIssuer); + TPM_Digest_Copy(dest_daa_tpm->DAA_digest_v0, src_daa_tpm->DAA_digest_v0); + TPM_Digest_Copy(dest_daa_tpm->DAA_digest_v1, src_daa_tpm->DAA_digest_v1); + TPM_Digest_Copy(dest_daa_tpm->DAA_rekey, src_daa_tpm->DAA_rekey); + dest_daa_tpm->DAA_count = src_daa_tpm->DAA_count; + return; +} + +/* + TPM_DAA_CONTEXT +*/ + +/* TPM_DAAContext_Init() + + sets members to default values + sets all pointers to NULL and sizes to 0 + always succeeds - no return code +*/ + +void TPM_DAAContext_Init(TPM_DAA_CONTEXT *tpm_daa_context) +{ + printf(" TPM_DAAContext_Init:\n"); + TPM_Digest_Init(tpm_daa_context->DAA_digestContext); + TPM_Digest_Init(tpm_daa_context->DAA_digest); + TPM_Nonce_Init(tpm_daa_context->DAA_contextSeed); + memset(tpm_daa_context->DAA_scratch, 0, sizeof(tpm_daa_context->DAA_scratch)); + tpm_daa_context->DAA_stage = 0; + tpm_daa_context->DAA_scratch_null = TRUE; + return; +} + +/* TPM_DAAContext_Load() + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DAAContext_Init() + After use, call TPM_DAAContext_Delete() to free memory +*/ + +TPM_RESULT TPM_DAAContext_Load(TPM_DAA_CONTEXT *tpm_daa_context, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAAContext_Load:\n"); + /* check tag */ + if (rc == 0) { + rc = TPM_CheckTag(TPM_TAG_DAA_CONTEXT, stream, stream_size); + } + /* load DAA_digestContext */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_context->DAA_digestContext, stream, stream_size); + } + /* load DAA_digest */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_context->DAA_digest, stream, stream_size); + } + /* load DAA_contextSeed */ + if (rc == 0) { + rc = TPM_Nonce_Load(tpm_daa_context->DAA_contextSeed, stream, stream_size); + } + /* load DAA_scratch */ + if (rc == 0) { + rc = TPM_Loadn(tpm_daa_context->DAA_scratch, sizeof(tpm_daa_context->DAA_scratch), + stream, stream_size); + } + /* load DAA_stage */ + if (rc == 0) { + rc = TPM_Load8(&(tpm_daa_context->DAA_stage), stream, stream_size); + } + /* load DAA_scratch_null */ + if (rc == 0) { + rc = TPM_LoadBool(&(tpm_daa_context->DAA_scratch_null), stream, stream_size); + } + return rc; +} + +/* TPM_DAAContext_Store() + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DAAContext_Store(TPM_STORE_BUFFER *sbuffer, + const TPM_DAA_CONTEXT *tpm_daa_context) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAAContext_Store:\n"); + /* store tag */ + if (rc == 0) { + rc = TPM_Sbuffer_Append16(sbuffer, TPM_TAG_DAA_CONTEXT); + } + /* store DAA_digestContext */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_context->DAA_digestContext); + } + /* store DAA_digest */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_context->DAA_digest); + } + /* store DAA_contextSeed */ + if (rc == 0) { + rc = TPM_Nonce_Store(sbuffer, tpm_daa_context->DAA_contextSeed); + } + /* store DAA_scratch */ + if (rc == 0) { + rc = TPM_Sbuffer_Append(sbuffer, tpm_daa_context->DAA_scratch, + sizeof(tpm_daa_context->DAA_scratch)); + } + /* store DAA_stage */ + if (rc == 0) { + rc = TPM_Sbuffer_Append(sbuffer, &(tpm_daa_context->DAA_stage), sizeof(BYTE)); + } + /* store DAA_scratch_null */ + if (rc == 0) { + rc = TPM_Sbuffer_Append(sbuffer, &(tpm_daa_context->DAA_scratch_null), sizeof(TPM_BOOL)); + } + return rc; +} + +/* TPM_DAAContext_Delete() + + No-OP if the parameter is NULL, else: + frees memory allocated for the object + sets pointers to NULL + calls TPM_DAAContext_Init to set members back to default values + The object itself is not freed +*/ + +void TPM_DAAContext_Delete(TPM_DAA_CONTEXT *tpm_daa_context) +{ + printf(" TPM_DAAContext_Delete:\n"); + if (tpm_daa_context != NULL) { + TPM_DAAContext_Init(tpm_daa_context); + } + return; +} + +/* TPM_DAAContext_Copy() copies the source to the destination + +*/ + +void TPM_DAAContext_Copy(TPM_DAA_CONTEXT *dest_daa_context, TPM_DAA_CONTEXT *src_daa_context) +{ + printf(" TPM_DAAContext_Copy:\n"); + TPM_Digest_Copy(dest_daa_context->DAA_digestContext, src_daa_context->DAA_digestContext); + TPM_Digest_Copy(dest_daa_context->DAA_digest, src_daa_context->DAA_digest); + TPM_Nonce_Copy(dest_daa_context->DAA_contextSeed, src_daa_context->DAA_contextSeed); + memcpy(dest_daa_context->DAA_scratch, src_daa_context->DAA_scratch, + sizeof(src_daa_context->DAA_scratch)); + dest_daa_context->DAA_stage = src_daa_context->DAA_stage; + dest_daa_context->DAA_scratch_null = src_daa_context->DAA_scratch_null; + return; +} + +/* + TPM_DAA_JOINDATA +*/ + +/* TPM_DAAJoindata_Init() + + sets members to default values + sets all pointers to NULL and sizes to 0 + always succeeds - no return code +*/ + +void TPM_DAAJoindata_Init(TPM_DAA_JOINDATA *tpm_daa_joindata) +{ + printf(" TPM_DAAJoindata_Init:\n"); + memset(tpm_daa_joindata->DAA_join_u0, 0, sizeof(tpm_daa_joindata->DAA_join_u0)); + memset(tpm_daa_joindata->DAA_join_u1, 0, sizeof(tpm_daa_joindata->DAA_join_u1)); + TPM_Digest_Init(tpm_daa_joindata->DAA_digest_n0); + return; +} + +/* TPM_DAAJoindata_Load() + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DAAJoindata_Init() + After use, call TPM_DAAJoindata_Delete() to free memory +*/ + +TPM_RESULT TPM_DAAJoindata_Load(TPM_DAA_JOINDATA *tpm_daa_joindata, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAAJoindata_Load:\n"); + /* load DAA_join_u0 */ + if (rc == 0) { + rc = TPM_Loadn(tpm_daa_joindata->DAA_join_u0, + sizeof(tpm_daa_joindata->DAA_join_u0), + stream, stream_size); + } + /* load DAA_join_u1 */ + if (rc == 0) { + rc = TPM_Loadn(tpm_daa_joindata->DAA_join_u1, + sizeof(tpm_daa_joindata->DAA_join_u1), + stream, stream_size); + } + /* load DAA_digest_n0 */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_joindata->DAA_digest_n0, stream, stream_size); + } + return rc; +} + +/* TPM_DAAJoindata_Store() + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DAAJoindata_Store(TPM_STORE_BUFFER *sbuffer, + const TPM_DAA_JOINDATA *tpm_daa_joindata) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAAJoindata_Store:\n"); + /* store DAA_join_u0 */ + if (rc == 0) { + rc = TPM_Sbuffer_Append(sbuffer, tpm_daa_joindata->DAA_join_u0, + sizeof(tpm_daa_joindata->DAA_join_u0)); + } + /* store DAA_join_u1 */ + if (rc == 0) { + rc = TPM_Sbuffer_Append(sbuffer, tpm_daa_joindata->DAA_join_u1, + sizeof(tpm_daa_joindata->DAA_join_u1)); + } + /* store DAA_digest_n0 */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_joindata->DAA_digest_n0); + } + return rc; +} + +/* TPM_DAAJoindata_Delete() + + No-OP if the parameter is NULL, else: + frees memory allocated for the object + sets pointers to NULL + calls TPM_DAAJoindata_Init to set members back to default values + The object itself is not freed +*/ + +void TPM_DAAJoindata_Delete(TPM_DAA_JOINDATA *tpm_daa_joindata) +{ + printf(" TPM_DAAJoindata_Delete:\n"); + if (tpm_daa_joindata != NULL) { + TPM_DAAJoindata_Init(tpm_daa_joindata); + } + return; +} + +/* TPM_DAAJoindata_Copy() copies the source to the destination + +*/ + +void TPM_DAAJoindata_Copy(TPM_DAA_JOINDATA *dest_daa_joindata, TPM_DAA_JOINDATA *src_daa_joindata) +{ + printf(" TPM_DAAJoindata_Copy:\n"); + memcpy(dest_daa_joindata->DAA_join_u0, src_daa_joindata->DAA_join_u0, + sizeof(src_daa_joindata->DAA_join_u0)); + memcpy(dest_daa_joindata->DAA_join_u1, src_daa_joindata->DAA_join_u1, + sizeof(src_daa_joindata->DAA_join_u1)); + TPM_Digest_Copy(dest_daa_joindata->DAA_digest_n0, src_daa_joindata->DAA_digest_n0); + return; +} + +/* + TPM_DAA_BLOB +*/ + +/* TPM_DAABlob_Init() + + sets members to default values + sets all pointers to NULL and sizes to 0 + always succeeds - no return code +*/ + +void TPM_DAABlob_Init(TPM_DAA_BLOB *tpm_daa_blob) +{ + printf(" TPM_DAABlob_Init:\n"); + tpm_daa_blob->resourceType = 0; + memset(tpm_daa_blob->label, 0, sizeof(tpm_daa_blob->label)); + TPM_Digest_Init(tpm_daa_blob->blobIntegrity); + TPM_SizedBuffer_Init(&(tpm_daa_blob->additionalData)); + TPM_SizedBuffer_Init(&(tpm_daa_blob->sensitiveData)); + return; +} + +/* TPM_DAABlob_Load() + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DAABlob_Init() + After use, call TPM_DAABlob_Delete() to free memory +*/ + +TPM_RESULT TPM_DAABlob_Load(TPM_DAA_BLOB *tpm_daa_blob, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAABlob_Load:\n"); + /* check tag */ + if (rc == 0) { + rc = TPM_CheckTag(TPM_TAG_DAA_BLOB, stream, stream_size); + } + /* load resourceType */ + if (rc == 0) { + rc = TPM_Load32(&(tpm_daa_blob->resourceType), stream, stream_size); + } + /* load label */ + if (rc == 0) { + rc = TPM_Loadn(tpm_daa_blob->label, sizeof(tpm_daa_blob->label), stream, stream_size); + } + /* load blobIntegrity */ + if (rc == 0) { + rc = TPM_Digest_Load(tpm_daa_blob->blobIntegrity, stream, stream_size); + } + /* load additionalData */ + if (rc == 0) { + rc = TPM_SizedBuffer_Load(&(tpm_daa_blob->additionalData), stream, stream_size); + } + /* load sensitiveData */ + if (rc == 0) { + rc = TPM_SizedBuffer_Load(&(tpm_daa_blob->sensitiveData), stream, stream_size); + } + return rc; +} + +/* TPM_DAABlob_Store() + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DAABlob_Store(TPM_STORE_BUFFER *sbuffer, + const TPM_DAA_BLOB *tpm_daa_blob) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAABlob_Store:\n"); + /* store tag */ + if (rc == 0) { + rc = TPM_Sbuffer_Append16(sbuffer, TPM_TAG_DAA_BLOB); + } + /* store resourceType */ + if (rc == 0) { + rc = TPM_Sbuffer_Append32(sbuffer, tpm_daa_blob->resourceType); + } + /* store label */ + if (rc == 0) { + rc = TPM_Sbuffer_Append(sbuffer, tpm_daa_blob->label, sizeof(tpm_daa_blob->label)); + } + /* store blobIntegrity */ + if (rc == 0) { + rc = TPM_Digest_Store(sbuffer, tpm_daa_blob->blobIntegrity); + } + /* store additionalData */ + if (rc == 0) { + rc = TPM_SizedBuffer_Store(sbuffer, &(tpm_daa_blob->additionalData)); + } + /* store sensitiveData */ + if (rc == 0) { + rc = TPM_SizedBuffer_Store(sbuffer, &(tpm_daa_blob->sensitiveData)); + } + return rc; +} + +/* TPM_DAABlob_Delete() + + No-OP if the parameter is NULL, else: + frees memory allocated for the object + sets pointers to NULL + calls TPM_DAABlob_Init to set members back to default values + The object itself is not freed +*/ + +void TPM_DAABlob_Delete(TPM_DAA_BLOB *tpm_daa_blob) +{ + printf(" TPM_DAABlob_Delete:\n"); + if (tpm_daa_blob != NULL) { + TPM_SizedBuffer_Delete(&(tpm_daa_blob->additionalData)); + TPM_SizedBuffer_Delete(&(tpm_daa_blob->sensitiveData)); + TPM_DAABlob_Init(tpm_daa_blob); + } + return; +} + +/* + TPM_DAA_SENSITIVE +*/ + +/* TPM_DAASensitive_Init() + + sets members to default values + sets all pointers to NULL and sizes to 0 + always succeeds - no return code +*/ + +void TPM_DAASensitive_Init(TPM_DAA_SENSITIVE *tpm_daa_sensitive) +{ + printf(" TPM_DAASensitive_Init:\n"); + TPM_SizedBuffer_Init(&(tpm_daa_sensitive->internalData)); + return; +} + +/* TPM_DAASensitive_Load() + + deserialize the structure from a 'stream' + 'stream_size' is checked for sufficient data + returns 0 or error codes + + Before use, call TPM_DAASensitive_Init() + After use, call TPM_DAASensitive_Delete() to free memory +*/ + +TPM_RESULT TPM_DAASensitive_Load(TPM_DAA_SENSITIVE *tpm_daa_sensitive, + unsigned char **stream, + uint32_t *stream_size) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAASensitive_Load:\n"); + /* check tag */ + if (rc == 0) { + rc = TPM_CheckTag(TPM_TAG_DAA_SENSITIVE, stream, stream_size); + } + /* load internalData */ + if (rc == 0) { + rc = TPM_SizedBuffer_Load(&(tpm_daa_sensitive->internalData), stream, stream_size); + } + return rc; +} + +/* TPM_DAASensitive_Store() + + serialize the structure to a stream contained in 'sbuffer' + returns 0 or error codes +*/ + +TPM_RESULT TPM_DAASensitive_Store(TPM_STORE_BUFFER *sbuffer, + const TPM_DAA_SENSITIVE *tpm_daa_sensitive) +{ + TPM_RESULT rc = 0; + + printf(" TPM_DAASensitive_Store:\n"); + /* store tag */ + if (rc == 0) { + rc = TPM_Sbuffer_Append16(sbuffer, TPM_TAG_DAA_SENSITIVE); + } + /* store internalData */ + if (rc == 0) { + rc = TPM_SizedBuffer_Store(sbuffer, &(tpm_daa_sensitive->internalData)); + } + return rc; +} + +/* TPM_DAASensitive_Delete() + + No-OP if the parameter is NULL, else: + frees memory allocated for the object + sets pointers to NULL + calls TPM_DAASensitive_Init to set members back to default values + The object itself is not freed +*/ + +void TPM_DAASensitive_Delete(TPM_DAA_SENSITIVE *tpm_daa_sensitive) +{ + printf(" TPM_DAASensitive_Delete:\n"); + if (tpm_daa_sensitive != NULL) { + TPM_SizedBuffer_Delete(&(tpm_daa_sensitive->internalData)); + TPM_DAASensitive_Init(tpm_daa_sensitive); + } + return; +} + + +/* + Processing Common Stage Functions +*/ + +TPM_RESULT TPM_DAAJoin_Stage00(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA **tpm_daa_session_data, + TPM_BOOL *daaHandleValid, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *stream; + uint32_t stream_size; + uint32_t count; + TPM_HANDLE daaHandle = 0; /* no preassigned handle */ + + printf("TPM_DAAJoin_Stage00:\n"); + if (rc == 0) { + /* a. Determine that sufficient resources are available to perform a TPM_DAA_Join. */ + /* i. The TPM MUST support sufficient resources to perform one (1) + TPM_DAA_Join/TPM_DAA_Sign. The TPM MAY support additional TPM_DAA_Join/TPM_DAA_Sign + sessions. */ + /* ii. The TPM may share internal resources between the DAA operations and other variable + resource requirements: */ + /* iii. If there are insufficient resources within the stored key pool (and one or more keys + need to be removed to permit the DAA operation to execute) return TPM_NOSPACE */ + /* iv. If there are insufficient resources within the stored session pool (and one or more + authorization or transport sessions need to be removed to permit the DAA operation to + execute), return TPM_RESOURCES. */ + rc = TPM_DaaSessions_GetNewHandle(tpm_daa_session_data, + &daaHandle, /* output */ + daaHandleValid, /* output */ + tpm_state->tpm_stclear_data.daaSessions); /* array */ + } + if (rc == 0) { + /* b. Set all fields in DAA_issuerSettings = NULL */ + /* c. set all fields in DAA_tpmSpecific = NULL */ + /* d. set all fields in DAA_session = NULL */ + /* e. Set all fields in DAA_joinSession = NULL */ + /* NOTE Done by TPM_DaaSessions_GetNewHandle() */ + /* f. Verify that sizeOf(inputData0) == sizeof(DAA_tpmSpecific -> DAA_count) and return + error TPM_DAA_INPUT_DATA0 on mismatch */ + if (inputData0->size != sizeof((*tpm_daa_session_data)->DAA_tpmSpecific.DAA_count)) { + printf("TPM_DAAJoin_Stage00: Error, inputData0 size %u should be %lu\n", + inputData0->size, + (unsigned long)sizeof((*tpm_daa_session_data)->DAA_tpmSpecific.DAA_count)); + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + /* g. Verify that inputData0 > 0, and return error TPM_DAA_INPUT_DATA0 on mismatch */ + stream = inputData0->buffer; + stream_size = inputData0->size; + rc = TPM_Load32(&count, &stream, &stream_size); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + printf("TPM_DAAJoin_Stage00: count %u\n", count); + if (count == 0) { + printf("TPM_DAAJoin_Stage00: Error, count is zero\n"); + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + /* h. Set DAA_tpmSpecific -> DAA_count = inputData0 */ + (*tpm_daa_session_data)->DAA_tpmSpecific.DAA_count = count; + /* i. set DAA_session -> DAA_digestContext = SHA-1(DAA_tpmSpecific || DAA_joinSession) */ + rc = TPM_DAADigestContext_GenerateDigestJoin + ((*tpm_daa_session_data)->DAA_session.DAA_digestContext, + (*tpm_daa_session_data)); + } + if (rc == 0) { + /* j. set DAA_session -> DAA_stage = 1 */ + (*tpm_daa_session_data)->DAA_session.DAA_stage = 1; + /* k. Assign session handle for TPM_DAA_Join */ + /* NOTE Done by TPM_DaaSessions_GetNewHandle() */ + printf("TPM_DAAJoin_Stage00: handle %08x\n", (*tpm_daa_session_data)->daaHandle); + /* l. set outputData = new session handle */ + /* i. The handle in outputData is included the output HMAC. */ + rc = TPM_SizedBuffer_Append32(outputData, (*tpm_daa_session_data)->daaHandle); + } + /* m. return TPM_SUCCESS */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage01(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + TPM_DIGEST signedDataDigest; + + printf("TPM_DAAJoin_Stage01:\n"); + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==1. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that sizeOf(inputData0) == DAA_SIZE_issuerModulus and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + if (inputData0->size != DAA_SIZE_issuerModulus) { + printf("TPM_DAAJoin_Stage01: Error, bad input0 size %u\n", inputData0->size); + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + /* d. If DAA_session -> DAA_scratch == NULL: */ + if (tpm_daa_session_data->DAA_session.DAA_scratch_null) { + printf("TPM_DAAJoin_Stage01: DAA_scratch null\n"); + if (rc == 0) { + /* i. Set DAA_session -> DAA_scratch = inputData0 */ + tpm_daa_session_data->DAA_session.DAA_scratch_null = FALSE; + memcpy(tpm_daa_session_data->DAA_session.DAA_scratch, + inputData0->buffer, DAA_SIZE_issuerModulus); + /* ii. set DAA_joinSession -> DAA_digest_n0 = SHA-1(DAA_session -> DAA_scratch) */ + rc = + TPM_SHA1(tpm_daa_session_data->DAA_joinSession.DAA_digest_n0, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + tpm_daa_session_data->DAA_session.DAA_scratch, + 0, NULL); + } + /* iii. set DAA_tpmSpecific -> DAA_rekey = SHA-1(tpmDAASeed || DAA_joinSession -> + DAA_digest_n0) */ + if (rc == 0) { + rc = TPM_SHA1(tpm_daa_session_data->DAA_tpmSpecific.DAA_rekey, + TPM_NONCE_SIZE, tpm_state->tpm_permanent_data.tpmDAASeed, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_joinSession.DAA_digest_n0, + 0, NULL); + } + } + /* e. Else (If DAA_session -> DAA_scratch != NULL): */ + else { + printf("TPM_DAAJoin_Stage01: DAA_scratch not null\n"); + /* i. Set signedData = inputData0 */ + /* ii. Verify that sizeOf(inputData1) == DAA_SIZE_issuerModulus and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + if (inputData1->size != DAA_SIZE_issuerModulus) { + printf("TPM_DAAJoin_Stage01: Error, bad input1 size %u\n", inputData1->size); + rc = TPM_DAA_INPUT_DATA1; + } + } + /* iii. Set signatureValue = inputData1 */ + /* iv. Use the RSA key == [DAA_session -> DAA_scratch] to verify that signatureValue is + a signature on signedData using TPM_SS_RSASSAPKCS1v15_SHA1 (RSA PKCS1.5 with SHA-1), + and return error TPM_DAA_ISSUER_VALIDITY on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage01: Digesting signedData\n"); + rc = TPM_SHA1(signedDataDigest, + inputData0->size, inputData0->buffer, + 0, NULL); + } + if (rc == 0) { + printf("TPM_DAAJoin_Stage01: Verifying signature\n"); + rc = TPM_RSAVerify(inputData1->buffer, /* signature */ + inputData1->size, + TPM_SS_RSASSAPKCS1v15_INFO, /* signature scheme */ + signedDataDigest, /* signed data */ + TPM_DIGEST_SIZE, + tpm_daa_session_data->DAA_session.DAA_scratch, /* pub modulus */ + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + tpm_default_rsa_exponent, /* public exponent */ + 3); + if (rc != 0) { + printf("TPM_DAAJoin_Stage01: Error, bad signature\n"); + rc = TPM_DAA_ISSUER_VALIDITY; + } + } + /* v. Set DAA_session -> DAA_scratch = signedData */ + if (rc == 0) { + memcpy(tpm_daa_session_data->DAA_session.DAA_scratch, + inputData0->buffer, inputData1->size); + } + } + } + if (rc == 0) { + /* f. Decrement DAA_tpmSpecific -> DAA_count by 1 (unity) */ + tpm_daa_session_data->DAA_tpmSpecific.DAA_count--; + /* g. If DAA_tpmSpecific -> DAA_count ==0: */ + if (tpm_daa_session_data->DAA_tpmSpecific.DAA_count == 0) { + /* h. increment DAA_session -> DAA_Stage by 1 */ + tpm_daa_session_data->DAA_session.DAA_stage++; + } + /* i. set DAA_session -> DAA_digestContext = SHA-1(DAA_tpmSpecific || DAA_joinSession) */ + rc = TPM_DAADigestContext_GenerateDigestJoin + (tpm_daa_session_data->DAA_session.DAA_digestContext, tpm_daa_session_data); + } + /* j. set outputData = NULL */ + /* NOTE Done by caller */ + /* k. return TPM_SUCCESS */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage02(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + unsigned char *stream; + uint32_t stream_size; + TPM_STORE_BUFFER signedDataSbuffer; + TPM_DIGEST signedDataDigest; + + printf("TPM_DAAJoin_Stage02:\n"); + outputData = outputData; /* not used */ + tpm_state = tpm_state; /* not used */ + TPM_Sbuffer_Init(&signedDataSbuffer); /* freed @1*/ + /* a. Verify that DAA_session ->DAA_stage==2. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that sizeOf(inputData0) == sizeOf(TPM_DAA_ISSUER) and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + /* NOTE cannot use sizeof because packing may not be exact */ + /* d. Set DAA_issuerSettings = inputData0. Verify that all fields in DAA_issuerSettings are + present and return error TPM_DAA_INPUT_DATA0 if not. */ + if (rc == 0) { + stream = inputData0->buffer; + stream_size = inputData0->size; + rc = TPM_DAAIssuer_Load(&(tpm_daa_session_data->DAA_issuerSettings), &stream, &stream_size); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + if (stream_size != 0) { + printf("TPM_DAAJoin_Stage02: Error, bad input0 size %u\n", inputData0->size); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Verify that sizeOf(inputData1) == DAA_SIZE_issuerModulus and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + if (inputData1->size != DAA_SIZE_issuerModulus) { + printf("TPM_DAAJoin_Stage02: Error, bad input1 size %u\n", inputData1->size); + rc = TPM_DAA_INPUT_DATA1; + } + } + /* f. Set signatureValue = inputData1 */ + /* g. Set signedData = (DAA_joinSession -> DAA_digest_n0 || DAA_issuerSettings) */ + if (rc == 0) { + rc = TPM_Digest_Store(&signedDataSbuffer, + tpm_daa_session_data->DAA_joinSession.DAA_digest_n0); + } + if (rc == 0) { + rc = TPM_DAAIssuer_Store(&signedDataSbuffer, &(tpm_daa_session_data->DAA_issuerSettings)); + } + /* h. Use the RSA key [DAA_session -> DAA_scratch] to verify that signatureValue is a */ + /* signature on signedData using TPM_SS_RSASSAPKCS1v15_SHA1 (RSA PKCS1.5 with SHA-1), and return + error TPM_DAA_ISSUER_VALIDITY on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage02: Digesting signedData\n"); + rc = TPM_SHA1Sbuffer(signedDataDigest, &signedDataSbuffer); + } + if (rc == 0) { + printf("TPM_DAAJoin_Stage02: Verifying signature\n"); + rc = TPM_RSAVerify(inputData1->buffer, /* signature */ + inputData1->size, + TPM_SS_RSASSAPKCS1v15_INFO, /* signature scheme */ + signedDataDigest, /* signed data */ + TPM_DIGEST_SIZE, + tpm_daa_session_data->DAA_session.DAA_scratch, /* public modulus */ + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + tpm_default_rsa_exponent, /* public exponent */ + 3); + if (rc != 0) { + printf("TPM_DAAJoin_Stage02: Error, bad signature\n"); + rc = TPM_DAA_ISSUER_VALIDITY; + } + } + /* i. Set DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) */ + if (rc == 0) { + rc = TPM_SHA1_GenerateStructure(tpm_daa_session_data->DAA_tpmSpecific.DAA_digestIssuer, + &(tpm_daa_session_data->DAA_issuerSettings), + (TPM_STORE_FUNCTION_T)TPM_DAAIssuer_Store); + } + /* j. set DAA_session -> DAA_digestContext = SHA-1(DAA_tpmSpecific || DAA_joinSession) */ + if (rc == 0) { + rc = TPM_DAADigestContext_GenerateDigestJoin + (tpm_daa_session_data->DAA_session.DAA_digestContext, tpm_daa_session_data); + } + if (rc == 0) { + /* k. Set DAA_session -> DAA_scratch = NULL */ + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + /* l. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + } + /* m. return TPM_SUCCESS */ + TPM_Sbuffer_Delete(&signedDataSbuffer); /* @1*/ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage03(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *stream; + uint32_t stream_size; + + printf("TPM_DAAJoin_Stage03:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==3. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Verify that sizeOf(inputData0) == sizeOf(DAA_tpmSpecific -> DAA_count) and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + if (inputData0->size != sizeof(tpm_daa_session_data->DAA_tpmSpecific.DAA_count)) { + printf("TPM_DAAJoin_Stage03: Error, inputData0 size %u should be %lu\n", + inputData0->size, + (unsigned long)sizeof(tpm_daa_session_data->DAA_tpmSpecific.DAA_count)); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Set DAA_tpmSpecific -> DAA_count = inputData0 */ + if (rc == 0) { + stream = inputData0->buffer; + stream_size = inputData0->size; + rc = TPM_Load32(&(tpm_daa_session_data->DAA_tpmSpecific.DAA_count), &stream, &stream_size); + } + /* f. Obtain random data from the RNG and store it as DAA_joinSession -> DAA_join_u0 */ + if (rc == 0) { + rc = TPM_Random(tpm_daa_session_data->DAA_joinSession.DAA_join_u0, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u0)); + } + /* g. Obtain random data from the RNG and store it as DAA_joinSession -> DAA_join_u1 */ + if (rc == 0) { + rc = TPM_Random(tpm_daa_session_data->DAA_joinSession.DAA_join_u1, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u1)); + } + /* h. set outputData = NULL */ + /* NOTE Done by caller */ + /* i. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* j. set DAA_session -> DAA_digestContext = SHA-1(DAA_tpmSpecific || DAA_joinSession) */ + if (rc == 0) { + rc = TPM_DAADigestContext_GenerateDigestJoin + (tpm_daa_session_data->DAA_session.DAA_digestContext, tpm_daa_session_data); + } + /* k. return TPM_SUCCESS */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage04(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM xBignum = NULL; /* freed @1 */ + TPM_BIGNUM nBignum = NULL; /* freed @2 */ + TPM_BIGNUM fBignum = NULL; /* freed @3 */ + TPM_BIGNUM rBignum = NULL; /* freed @4 */ + + printf("TPM_DAAJoin_Stage04:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==4. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_R0 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_R0) == DAA_issuerSettings -> DAA_digest_R0 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage04: Checking DAA_generic_R0\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_R0, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_R0 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage04: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Set X = DAA_generic_R0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage04: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* i. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage04: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* j. Set f = SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 0) || + SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 1 ) mod + DAA_issuerSettings -> DAA_generic_q */ + if (rc == 0) { + rc = TPM_ComputeF(&fBignum, tpm_daa_session_data); /* freed @3 */ + } + /* k. Set f0 = f mod 2^DAA_power0 (erase all but the lowest DAA_power0 bits of f) */ + if (rc == 0) { + rc = TPM_BN_mask_bits(fBignum, DAA_power0); /* f becomes f0 */ + } + /* l. Set DAA_session -> DAA_scratch = (X^f0) mod n */ + if (rc == 0) { + rc = TPM_ComputeAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + &rBignum, /* R */ + xBignum, /* A */ + fBignum, /* P */ + nBignum); /* n */ + } + /* m. set outputData = NULL */ + /* NOTE Done by caller */ + /* n. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* o. return TPM_SUCCESS */ + TPM_BN_free(xBignum); /* @1 */ + TPM_BN_free(nBignum); /* @2 */ + TPM_BN_free(fBignum); /* @3 */ + TPM_BN_free(rBignum); /* @4 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage05(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM xBignum = NULL; /* freed @1 */ + TPM_BIGNUM nBignum = NULL; /* freed @2 */ + TPM_BIGNUM fBignum = NULL; /* freed @3 */ + TPM_BIGNUM f1Bignum = NULL; /* freed @4 */ + TPM_BIGNUM zBignum = NULL; /* freed @5 */ + + printf("TPM_DAAJoin_Stage05:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==5. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_R1 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_R1) == DAA_issuerSettings -> DAA_digest_R1 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage05: Checking DAA_generic_R1\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_R1, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_R1 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage05: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Set X = DAA_generic_R1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage05: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* i. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage05: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* j. Set f = SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 0) || + SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 1 ) mod + DAA_issuerSettings -> DAA_generic_q. */ + if (rc == 0) { + rc = TPM_ComputeF(&fBignum, tpm_daa_session_data); /* freed @3 */ + } + /* k. Shift f right by DAA_power0 bits (discard the lowest DAA_power0 bits) and label the result + f1 */ + if (rc == 0) { + rc = TPM_BN_rshift(&f1Bignum, fBignum, DAA_power0); /* f becomes f1 */ + } + /* l. Set Z = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage05: Creating Z\n"); + rc = TPM_bin2bn(&zBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* m. Set DAA_session -> DAA_scratch = Z*(X^f1) mod n */ + if (rc == 0) { + rc = TPM_ComputeZxAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + zBignum, /* Z */ + xBignum, /* A */ + f1Bignum, /* P */ + nBignum); /* N */ + } + /* n. set outputData = NULL */ + /* NOTE Done by caller */ + /* o. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* p. return TPM_SUCCESS */ + TPM_BN_free(xBignum); /* @1 */ + TPM_BN_free(nBignum); /* @2 */ + TPM_BN_free(fBignum); /* @3 */ + TPM_BN_free(f1Bignum); /* @4 */ + TPM_BN_free(zBignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage06(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM xBignum = NULL; /* freed @1 */ + TPM_BIGNUM nBignum = NULL; /* freed @2 */ + TPM_BIGNUM zBignum = NULL; /* freed @3 */ + TPM_BIGNUM yBignum = NULL; /* freed @4 */ + + printf("TPM_DAAJoin_Stage06:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==6. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_S0 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_S0) == DAA_issuerSettings -> DAA_digest_S0 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage06: Checking DAA_generic_S0\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_S0, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_S0 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage06: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Set X = DAA_generic_S0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage06: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* i. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage06: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* j. Set Z = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage06: Creating Z\n"); + rc = TPM_bin2bn(&zBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* k. Set Y = DAA_joinSession -> DAA_join_u0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage06: Creating Y\n"); + rc = TPM_bin2bn(&yBignum, + tpm_daa_session_data->DAA_joinSession.DAA_join_u0, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u0)); + } + /* l. Set DAA_session -> DAA_scratch = Z*(X^Y) mod n */ + if (rc == 0) { + rc = TPM_ComputeZxAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + zBignum, /* Z */ + xBignum, /* A */ + yBignum, /* P */ + nBignum); /* N */ + } + /* m. set outputData = NULL */ + /* NOTE Done by caller */ + /* n. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* o. return TPM_SUCCESS */ + TPM_BN_free(xBignum); /* @1 */ + TPM_BN_free(nBignum); /* @2 */ + TPM_BN_free(zBignum); /* @3 */ + TPM_BN_free(yBignum); /* @4 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage07(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + uint32_t nCount; /* DAA_count in nbo */ + TPM_BIGNUM xBignum = NULL; /* freed @1 */ + TPM_BIGNUM nBignum = NULL; /* freed @2 */ + TPM_BIGNUM yBignum = NULL; /* freed @3 */ + TPM_BIGNUM zBignum = NULL; /* freed @4 */ + + printf("TPM_DAAJoin_Stage07:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==7. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_S1 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_S1) == DAA_issuerSettings -> DAA_digest_S1 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage07: Checking DAA_generic_S1\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_S1, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_S1 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage07: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Set X = DAA_generic_S1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage07: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* i. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage07: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* j. Set Y = DAA_joinSession -> DAA_join_u1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage07: Creating Y\n"); + rc = TPM_bin2bn(&yBignum, + tpm_daa_session_data->DAA_joinSession.DAA_join_u1, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u1)); + } + /* k. Set Z = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage07: Creating Z\n"); + rc = TPM_bin2bn(&zBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* l. Set DAA_session -> DAA_scratch = Z*(X^Y) mod n */ + if (rc == 0) { + rc = TPM_ComputeZxAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + zBignum, /* Z */ + xBignum, /* A */ + yBignum, /* P */ + nBignum); /* N */ + } + /* m. Set DAA_session -> DAA_digest to the SHA-1 (DAA_session -> DAA_scratch || DAA_tpmSpecific + -> DAA_count || DAA_joinSession -> DAA_digest_n0) */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage07: Computing DAA_digest\n"); + nCount = htonl(tpm_daa_session_data->DAA_tpmSpecific.DAA_count); + rc = TPM_SHA1(tpm_daa_session_data->DAA_session.DAA_digest, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(uint32_t), &nCount, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_joinSession.DAA_digest_n0, + 0, NULL); + } + /* n. set outputData = DAA_session -> DAA_scratch */ + if (rc == 0) { + rc = TPM_SizedBuffer_Set(outputData, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + tpm_daa_session_data->DAA_session.DAA_scratch); + } + /* o. set DAA_session -> DAA_scratch = NULL */ + if (rc == 0) { + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + } + /* p. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* q. return TPM_SUCCESS */ + TPM_BN_free(xBignum); /* @1 */ + TPM_BN_free(nBignum); /* @2 */ + TPM_BN_free(yBignum); /* @3 */ + TPM_BN_free(zBignum); /* @4 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage08(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *NE = NULL; /* freed @1 */ + uint32_t NELength; + TPM_DIGEST outDigest; + + printf("TPM_DAAJoin_Stage08:\n"); + /* a. Verify that DAA_session ->DAA_stage==8. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Verify inputSize0 == DAA_SIZE_NE and return error TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + if (inputData0->size != DAA_SIZE_NE) { + printf("TPM_DAAJoin_Stage08: Error, inputData0 size %u should be %u\n", + inputData0->size, DAA_SIZE_NE); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Set NE = decrypt(inputData0, privEK) */ + if (rc == 0) { + rc = TPM_RSAPrivateDecryptMalloc(&NE, /* decrypted data */ + &NELength, /* length of data put into decrypt_data */ + inputData0->buffer, /* encrypted data */ + inputData0->size, /* encrypted data size */ + &(tpm_state->tpm_permanent_data.endorsementKey)); + } + /* f. set outputData = SHA-1(DAA_session -> DAA_digest || NE) */ + if (rc == 0) { + rc = TPM_SHA1(outDigest, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_session.DAA_digest, + NELength, NE, + 0, NULL); + } + if (rc == 0) { + rc = TPM_SizedBuffer_Set(outputData, TPM_DIGEST_SIZE, outDigest); + } + /* g. set DAA_session -> DAA_digest = NULL */ + if (rc == 0) { + TPM_Digest_Init(tpm_daa_session_data->DAA_session.DAA_digest); + } + /* h. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* i. return TPM_SUCCESS */ + free(NE); /* @1 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage09_Sign_Stage2(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + unsigned char *Y = NULL; /* freed @1 */ + TPM_BIGNUM yBignum = NULL; /* freed @2 */ + TPM_BIGNUM xBignum = NULL; /* freed @3 */ + TPM_BIGNUM nBignum = NULL; /* freed @4 */ + TPM_BIGNUM rBignum = NULL; /* freed @5 */ + + printf("TPM_DAAJoin_Stage09_Sign_Stage2:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==9. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific ||DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_R0 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_R0) == DAA_issuerSettings -> DAA_digest_R0 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage09_Sign_Stage2: Checking DAA_generic_R0\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_R0, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_R0 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage09_Sign_Stage2: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Obtain random data from the RNG and store it as DAA_session -> DAA_contextSeed */ + if (rc == 0) { + rc = TPM_Nonce_Generate(tpm_daa_session_data->DAA_session.DAA_contextSeed); + } + /* i. Obtain DAA_SIZE_r0 bytes using the MGF1 function and label them Y. "r0" || DAA_session -> + DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage09_Sign_Stage2: Creating Y\n"); + rc = TPM_MGF1_GenerateArray(&Y, /* returned MGF1 array */ + DAA_SIZE_r0, /* size of Y */ + /* length of the entire seed */ + sizeof("r0") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r0") -1, "r0", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&yBignum, Y, DAA_SIZE_r0); + } + /* j. Set X = DAA_generic_R0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage09_Sign_Stage2: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* k. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage09_Sign_Stage2: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* l. Set DAA_session -> DAA_scratch = (X^Y) mod n */ + if (rc == 0) { + rc = TPM_ComputeAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + &rBignum, /* R */ + xBignum, /* A */ + yBignum, /* P */ + nBignum); /* n */ + + } + /* m. set outputData = NULL */ + /* NOTE Done by caller */ + /* n. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* o. return TPM_SUCCESS */ + free(Y); /* @1 */ + TPM_BN_free(yBignum); /* @2 */ + TPM_BN_free(xBignum); /* @3 */ + TPM_BN_free(nBignum); /* @4 */ + TPM_BN_free(rBignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage10_Sign_Stage3(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + unsigned char *Y= NULL; /* freed @1 */ + TPM_BIGNUM xBignum = NULL; /* freed @2 */ + TPM_BIGNUM nBignum = NULL; /* freed @3 */ + TPM_BIGNUM zBignum = NULL; /* freed @4 */ + TPM_BIGNUM yBignum = NULL; /* freed @5*/ + + printf("TPM_DAAJoin_Stage10_Sign_Stage3:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==10. Return TPM_DAA_STAGE and flush handle on mismatch + h */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_R1 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_R1) == DAA_issuerSettings -> DAA_digest_R1 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage10_Sign_Stage3: Checking DAA_generic_R1\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_R1, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_R1 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage10_Sign_Stage3: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Obtain DAA_SIZE_r1 bytes using the MGF1 function and label them Y. "r1" || DAA_session -> + DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage10_Sign_Stage3: Creating Y\n"); + rc = TPM_MGF1_GenerateArray(&Y, /* returned MGF1 array */ + DAA_SIZE_r1, /* size of Y */ + /* length of the entire seed */ + sizeof("r1") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r1") -1, "r1", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&yBignum, Y, DAA_SIZE_r1); + } + /* i. Set X = DAA_generic_R1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage10_Sign_Stage3: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* j. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage10_Sign_Stage3: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* k. Set Z = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage10_Sign_Stage3: Creating Z\n"); + rc = TPM_bin2bn(&zBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* l. Set DAA_session -> DAA_scratch = Z*(X^Y) mod n */ + if (rc == 0) { + rc = TPM_ComputeZxAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + zBignum, /* Z */ + xBignum, /* A */ + yBignum, /* P */ + nBignum); /* N */ + } + /* m. set outputData = NULL */ + /* NOTE Done by caller */ + /* n. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* o. return TPM_SUCCESS */ + free(Y); /* @1 */ + TPM_BN_free(xBignum); /* @2 */ + TPM_BN_free(nBignum); /* @3 */ + TPM_BN_free(zBignum); /* @4 */ + TPM_BN_free(yBignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage11_Sign_Stage4(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + unsigned char *Y= NULL; /* freed @1 */ + TPM_BIGNUM yBignum = NULL; /* freed @2 */ + TPM_BIGNUM xBignum = NULL; /* freed @3 */ + TPM_BIGNUM nBignum = NULL; /* freed @4 */ + TPM_BIGNUM zBignum = NULL; /* freed @5 */ + + printf("TPM_DAAJoin_Stage11_Sign_Stage4:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==11. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_S0 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_S0) == DAA_issuerSettings -> DAA_digest_S0 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage11_Sign_Stage4: Checking DAA_generic_S0\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_S0, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_S0 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage11_Sign_Stage4: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Obtain DAA_SIZE_r2 bytes using the MGF1 function and label them Y. "r2" || DAA_session -> + DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage11_Sign_Stage4: Creating Y\n"); + rc = TPM_MGF1_GenerateArray(&Y, /* returned MGF1 array */ + DAA_SIZE_r2, /* size of Y */ + /* length of the entire seed */ + sizeof("r2") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r2") -1, "r2", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&yBignum, Y, DAA_SIZE_r2); + } + /* i. Set X = DAA_generic_S0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage11_Sign_Stage4: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* j. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage11_Sign_Stage4: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* k. Set Z = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage11_Sign_Stage4: Creating Z\n"); + rc = TPM_bin2bn(&zBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* l. Set DAA_session -> DAA_scratch = Z*(X^Y) mod n */ + if (rc == 0) { + rc = TPM_ComputeZxAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + zBignum, /* Z */ + xBignum, /* A */ + yBignum, /* P */ + nBignum); /* N */ + } + /* m. set outputData = NULL */ + /* NOTE Done by caller */ + /* n. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* o. return TPM_SUCCESS */ + free(Y); /* @1 */ + TPM_BN_free(yBignum); /* @2 */ + TPM_BN_free(xBignum); /* @3 */ + TPM_BN_free(nBignum); /* @4 */ + TPM_BN_free(zBignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage12(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + unsigned char *Y = NULL; /* freed @1 */ + TPM_BIGNUM yBignum = NULL; /* freed @2 */ + TPM_BIGNUM xBignum = NULL; /* freed @3 */ + TPM_BIGNUM nBignum = NULL; /* freed @4 */ + TPM_BIGNUM zBignum = NULL; /* freed @5 */ + + printf("TPM_DAAJoin_Stage12:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==12. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings ) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_S1 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_S1) == DAA_issuerSettings -> DAA_digest_S1 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage12: Checking DAA_generic_S1\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_S1, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_S1 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage12: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Obtain DAA_SIZE_r3 bytes using the MGF1 function and label them Y. "r3" || DAA_session -> + DAA_contextSeed) is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage12: Creating Y\n"); + rc = TPM_MGF1_GenerateArray(&Y, /* returned MGF1 array */ + DAA_SIZE_r3, /* size of Y */ + /* length of the entire seed */ + sizeof("r3") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r3") -1, "r3", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&yBignum, Y, DAA_SIZE_r3); + } + /* i. Set X = DAA_generic_S1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage12: Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* j. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage12: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* k. Set Z = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage12: Creating Z\n"); + rc = TPM_bin2bn(&zBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* l. Set DAA_session -> DAA_scratch = Z*(X^Y) mod n */ + if (rc == 0) { + rc = TPM_ComputeZxAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + zBignum, /* Z */ + xBignum, /* A */ + yBignum, /* P */ + nBignum); /* N */ + } + /* m. set outputData = DAA_session -> DAA_scratch */ + if (rc == 0) { + rc = TPM_SizedBuffer_Set(outputData, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + tpm_daa_session_data->DAA_session.DAA_scratch); + } + /* n. Set DAA_session -> DAA_scratch = NULL */ + if (rc == 0) { + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + } + /* o. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* p. return TPM_SUCCESS */ + free(Y); /* @1 */ + TPM_BN_free(yBignum); /* @2 */ + TPM_BN_free(xBignum); /* @3 */ + TPM_BN_free(nBignum); /* @4 */ + TPM_BN_free(zBignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage13_Sign_Stage6(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM wBignum = NULL; /* freed @1 */ + TPM_BIGNUM qBignum = NULL; /* freed @2 */ + TPM_BIGNUM nBignum = NULL; /* freed @3 */ + TPM_BIGNUM w1Bignum = NULL; /* freed @4 */ + + printf("TPM_DAAJoin_Stage13_Sign_Stage6:\n"); + tpm_state = tpm_state; /* not used */ + outputData = outputData; /* not used */ + /* a. Verify that DAA_session->DAA_stage==13. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_gamma = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_gamma) == DAA_issuerSettings -> DAA_digest_gamma and return + error TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage13_Sign_Stage6: Checking DAA_generic_gamma\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_gamma, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_gamma */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Verify that inputSize1 == DAA_SIZE_w and return error TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + if (inputData1->size != DAA_SIZE_w) { + printf("TPM_DAAJoin_Stage13_Sign_Stage6: Error, inputData1 size %u should be %u\n", + inputData0->size, DAA_SIZE_w); + rc = TPM_DAA_INPUT_DATA1; + } + } + /* g. Set w = inputData1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage13_Sign_Stage6: Creating w\n"); + rc = TPM_bin2bn(&wBignum, inputData1->buffer, inputData1->size); + } + /* FIXME added Set q = DAA_issuerSettings -> DAA_generic_q */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage13_Sign_Stage6: Creating q from DAA_generic_q\n"); + rc = TPM_bin2bn(&qBignum, + tpm_daa_session_data->DAA_issuerSettings.DAA_generic_q, + sizeof(tpm_daa_session_data->DAA_issuerSettings.DAA_generic_q)); + } + /* FIXME Set n = DAA_generic_gamma */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage13_Sign_Stage6: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData0->buffer, inputData0->size); + } + /* h. Set w1 = w^( DAA_issuerSettings -> DAA_generic_q) mod (DAA_generic_gamma) */ + /* FIXME w1 = (w^q) mod n */ + if (rc == 0) { + rc = TPM_ComputeAexpPmodn(NULL, + 0, + &w1Bignum, /* R */ + wBignum, /* A */ + qBignum, /* P */ + nBignum); /* n */ + } + /* i. If w1 != 1 (unity), return error TPM_DAA_WRONG_W */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage13_Sign_Stage6: Testing w1\n"); + rc = TPM_BN_is_one(w1Bignum); + } + /* j. Set DAA_session -> DAA_scratch = w */ + if (rc == 0) { + rc = TPM_ComputeDAAScratch(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + wBignum); + } + /* k. set outputData = NULL */ + /* NOTE Done by caller */ + /* l. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* m. return TPM_SUCCESS. */ + TPM_BN_free(wBignum); /* @1 */ + TPM_BN_free(qBignum); /* @2 */ + TPM_BN_free(nBignum); /* @3 */ + TPM_BN_free(w1Bignum); /* @4 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage14_Sign_Stage7(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM fBignum = NULL; /* freed @1 */ + TPM_BIGNUM wBignum = NULL; /* freed @2 */ + TPM_BIGNUM nBignum = NULL; /* freed @3 */ + TPM_BIGNUM eBignum = NULL; /* freed @4 */ + + unsigned int numBytes; /* for debug */ + + printf("TPM_DAAJoin_Stage14_Sign_Stage7:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==14. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings ) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_gamma = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_gamma) == DAA_issuerSettings -> DAA_digest_gamma and return + error TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage14_Sign_Stage7: Checking DAA_generic_gamma\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_gamma, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_gamma */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set f = SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 0) || + SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 1 ) mod + DAA_issuerSettings -> DAA_generic_q. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage14_Sign_Stage7: Creating f\n"); + rc = TPM_ComputeF(&fBignum, tpm_daa_session_data); /* freed @1 */ + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, fBignum); + printf("TPM_DAAJoin_Stage14_Sign_Stage7: f. f size %u\n", numBytes); + } + /* FIXME Set W = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage14_Sign_Stage7: Creating W\n"); + rc = TPM_bin2bn(&wBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, wBignum); + printf("TPM_DAAJoin_Stage14_Sign_Stage7: W size %u\n", numBytes); + } + /* FIXME Set n = DAA_generic_gamma */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage14_Sign_Stage7: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData0->buffer, inputData0->size); + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, nBignum); + printf("TPM_DAAJoin_Stage14_Sign_Stage7: n size %u\n", numBytes); + } + /* g. Set E = ((DAA_session -> DAA_scratch)^f) mod (DAA_generic_gamma). */ + /* FIXME E = (w^f) mod n */ + if (rc == 0) { + rc = TPM_ComputeAexpPmodn(NULL, + 0, + &eBignum, /* R */ + wBignum, /* A */ + fBignum, /* P */ + nBignum); /* n */ + } + /* h. Set outputData = E */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage14_Sign_Stage7: Output E\n"); + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + eBignum, 0); + } + /* i. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* j. return TPM_SUCCESS. */ + TPM_BN_free(fBignum); /* @1 */ + TPM_BN_free(wBignum); /* @2 */ + TPM_BN_free(nBignum); /* @3 */ + TPM_BN_free(eBignum); /* @4 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage15_Sign_Stage8(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *r0 = NULL; /* freed @1 */ + unsigned char *r1 = NULL; /* freed @2 */ + TPM_BIGNUM r0Bignum = NULL; /* freed @3 */ + TPM_BIGNUM r1Bignum = NULL; /* freed @4 */ + TPM_BIGNUM r1sBignum = NULL; /* freed @5 */ + TPM_BIGNUM rBignum = NULL; /* freed @6 */ + TPM_BIGNUM e1Bignum = NULL; /* freed @7 */ + TPM_BIGNUM qBignum = NULL; /* freed @8 */ + TPM_BIGNUM nBignum = NULL; /* freed @9 */ + TPM_BIGNUM wBignum = NULL; /* freed @10 */ + + printf("TPM_DAAJoin_Stage15_Sign_Stage8:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==15. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_gamma = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_gamma) == DAA_issuerSettings -> DAA_digest_gamma and return + error TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage15_Sign_Stage8: Checking DAA_generic_gamma\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_gamma, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_gamma */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Obtain DAA_SIZE_r0 bytes using the MGF1 function and label them r0. "r0" || DAA_session + -> DAA_contextSeed) is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage15_Sign_Stage8: Creating r0\n"); + rc = TPM_MGF1_GenerateArray(&r0, /* returned MGF1 array */ + DAA_SIZE_r0, /* size of Y */ + /* length of the entire seed */ + sizeof("r0") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r0") -1, "r0", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r0Bignum, r0, DAA_SIZE_r0); + } + /* g. Obtain DAA_SIZE_r1 bytes using the MGF1 function and label them r1. "r1" || DAA_session + -> DAA_contextSeedis the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage15_Sign_Stage8: Creating r1\n"); + rc = TPM_MGF1_GenerateArray(&r1, /* returned MGF1 array */ + DAA_SIZE_r1, /* size of Y */ + /* length of the entire seed */ + sizeof("r1") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r1") -1, "r1", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r1Bignum, r1, DAA_SIZE_r1); + } + /* FIXME Set q = DAA_generic_q */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage15_Sign_Stage8: Creating n from DAA_generic_q\n"); + rc = TPM_bin2bn(&qBignum, + tpm_daa_session_data->DAA_issuerSettings.DAA_generic_q, + sizeof(tpm_daa_session_data->DAA_issuerSettings.DAA_generic_q)); + } + /* h. set r = r0 + 2^DAA_power0 * r1 mod (DAA_issuerSettings -> DAA_generic_q). */ + /* FIXME added parentheses + h. set r = (r0 + (2^DAA_power0 * r1)) mod (DAA_issuerSettings -> DAA_generic_q). + h. set r = (r0 + (2^DAA_power0 * r1)) mod q */ + if (rc == 0) { + rc = TPM_BN_lshift(&r1sBignum, /* result, freed @5 */ + r1Bignum, /* input */ + DAA_power0); /* n */ + } + if (rc == 0) { + rc = TPM_ComputeApBmodn(&rBignum, /* result, freed @6 */ + r0Bignum, /* A */ + r1sBignum, /* B */ + qBignum); /* n */ + } + /* FIXME Set n = DAA_generic_gamma */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage15_Sign_Stage8: Creating n1 from DAA_generic_gamma\n"); + rc = TPM_bin2bn(&nBignum, inputData0->buffer, inputData0->size); + } + /* FIXME Set w = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage15_Sign_Stage8: Creating w from DAA_scratch\n"); + rc = TPM_bin2bn(&wBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* i. set E1 = ((DAA_session -> DAA_scratch)^r) mod (DAA_generic_gamma). */ + /* (w ^ r) mod n */ + if (rc == 0) { + rc = TPM_ComputeAexpPmodn(NULL, + 0, + &e1Bignum, /* R */ + wBignum, /* A */ + rBignum, /* P */ + nBignum); /* n */ + } + /* j. Set DAA_session -> DAA_scratch = NULL */ + if (rc == 0) { + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + } + /* k. Set outputData = E1 */ + if (rc == 0) { + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + e1Bignum, 0); + } + /* l. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* m. return TPM_SUCCESS. */ + free(r0); /* @1 */ + free(r1); /* @2 */ + TPM_BN_free(r0Bignum); /* @3 */ + TPM_BN_free(r1Bignum); /* @4 */ + TPM_BN_free(r1sBignum); /* @5 */ + TPM_BN_free(rBignum); /* @6 */ + TPM_BN_free(e1Bignum); /* @7 */ + TPM_BN_free(qBignum); /* @8 */ + TPM_BN_free(nBignum); /* @9 */ + TPM_BN_free(wBignum); /* @10 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage16_Sign_Stage9(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *nt = NULL; /* freed @1 */ + + printf("TPM_DAAJoin_Stage16_Sign_Stage9:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==16. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Verify that inputSize0 == sizeOf(TPM_DIGEST) and return error TPM_DAA_INPUT_DATA0 on + mismatch */ + if (rc == 0) { + if (inputData0->size != TPM_DIGEST_SIZE) { + printf("TPM_DAAJoin_Stage16_Sign_Stage9: Error, inputData0 size %u should be %u\n", + inputData0->size, TPM_DIGEST_SIZE); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Set DAA_session -> DAA_digest = inputData0 */ + if (rc == 0) { + /* e. Set DAA_session -> DAA_digest = inputData0 */ + /* NOTE: This step is unnecessary, since the value is overridden in g. */ + /* f. Obtain DAA_SIZE_NT bytes from the RNG and label them NT */ + rc = TPM_Malloc(&nt, DAA_SIZE_NT); + } + if (rc == 0) { + rc = TPM_Random(nt, DAA_SIZE_NT); + } + /* g. Set DAA_session -> DAA_digest to the SHA-1 ( DAA_session -> DAA_digest || NT ) */ + if (rc == 0) { + rc = TPM_SHA1(tpm_daa_session_data->DAA_session.DAA_digest, + inputData0->size, inputData0->buffer, /* e. DAA_session -> DAA_digest */ + DAA_SIZE_NT, nt, + 0, NULL); + } + /* h. Set outputData = NT */ + if (rc == 0) { + rc = TPM_SizedBuffer_Set(outputData, DAA_SIZE_NT, nt); + } + /* i. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* j. return TPM_SUCCESS. */ + free(nt); /* @1 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage17_Sign_Stage11(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData) +{ + TPM_RESULT rc = 0; + unsigned char *r0 = NULL; /* freed @1 */ + TPM_BIGNUM r0Bignum = NULL; /* freed @2 */ + TPM_BIGNUM fBignum = NULL; /* freed @3 */ + TPM_BIGNUM s0Bignum = NULL; /* freed @4 */ + TPM_BIGNUM cBignum = NULL; /* freed @5 */ + + printf("TPM_DAAJoin_Stage17_Sign_Stage11:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==17. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Obtain DAA_SIZE_r0 bytes using the MGF1 function and label them r0. "r0" || DAA_session + -> DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage17_Sign_Stage11: Creating r0\n"); + rc = TPM_MGF1_GenerateArray(&r0, /* returned MGF1 array */ + DAA_SIZE_r0, /* size of Y */ + /* length of the entire seed */ + sizeof("r0") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r0") -1, "r0", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r0Bignum, r0, DAA_SIZE_r0); + } + /* e. Set f = SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 0) || + SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 1 ) mod + DAA_issuerSettings -> DAA_generic_q. */ + if (rc == 0) { + rc = TPM_ComputeF(&fBignum, tpm_daa_session_data); /* freed @3 */ + } + /* f. Set f0 = f mod 2^DAA_power0 (erase all but the lowest DAA_power0 bits of f) */ + if (rc == 0) { + rc = TPM_BN_mask_bits(fBignum, DAA_power0); /* f becomes f0 */ + } + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage17_Sign_Stage11: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* g. Set s0 = r0 + (DAA_session -> DAA_digest) * f0 in Z. Compute over the integers. The + computation is not reduced with a modulus. */ + /* s0 = r0 + (c * f0) */ + if (rc == 0) { + rc = TPM_ComputeApBxC(&s0Bignum, /* result */ + r0Bignum, /* A */ + cBignum, /* B */ + fBignum); /* C */ + } + /* h. set outputData = s0 */ + if (rc == 0) { + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + s0Bignum, 0); + } + /* i. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* j. return TPM_SUCCESS */ + free(r0); /* @1 */ + TPM_BN_free(r0Bignum); /* @2 */ + TPM_BN_free(fBignum); /* @3 */ + TPM_BN_free(s0Bignum); /* @4 */ + TPM_BN_free(cBignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage18_Sign_Stage12(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData) +{ + TPM_RESULT rc = 0; + unsigned char *r1 = NULL; /* freed @1 */ + TPM_BIGNUM r1Bignum = NULL; /* freed @2 */ + TPM_BIGNUM fBignum = NULL; /* freed @3 */ + TPM_BIGNUM f1Bignum = NULL; /* freed @4 */ + TPM_BIGNUM s1Bignum = NULL; /* freed @5 */ + TPM_BIGNUM cBignum = NULL; /* freed @6 */ + + printf("TPM_DAAJoin_Stage18_Sign_Stage12:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==18. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Obtain DAA_SIZE_r1 bytes using the MGF1 function and label them r1. "r1" || DAA_session + -> DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage18_Sign_Stage12: Creating r1\n"); + rc = TPM_MGF1_GenerateArray(&r1, /* returned MGF1 array */ + DAA_SIZE_r1, /* size of Y */ + /* length of the entire seed */ + sizeof("r1") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r1") -1, "r1", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r1Bignum, r1, DAA_SIZE_r1); + } + /* e. Set f = SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 0) || + SHA-1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 1 ) mod + DAA_issuerSettings -> DAA_generic_q. */ + if (rc == 0) { + rc = TPM_ComputeF(&fBignum, tpm_daa_session_data); /* freed @3 */ + } + /* f. Shift f right by DAA_power0 bits (discard the lowest DAA_power0 bits) and label the result + f1 */ + if (rc == 0) { + rc = TPM_BN_rshift(&f1Bignum, fBignum, DAA_power0); /* f becomes f1 */ + } + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage18_Sign_Stage12: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* g. Set s1 = r1 + (DAA_session -> DAA_digest)* f1 in Z. Compute over the integers. The + computation is not reduced with a modulus. */ + /* s1 = r1 + (c * f1) */ + if (rc == 0) { + rc = TPM_ComputeApBxC(&s1Bignum, /* result */ + r1Bignum, /* A */ + cBignum, /* B */ + f1Bignum); /* C */ + } + /* h. set outputData = s1 */ + if (rc == 0) { + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + s1Bignum, 0); + } + /* i. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* j. return TPM_SUCCESS */ + free(r1); /* @1 */ + TPM_BN_free(r1Bignum); /* @2 */ + TPM_BN_free(fBignum); /* @3 */ + TPM_BN_free(f1Bignum); /* @4 */ + TPM_BN_free(s1Bignum); /* @5 */ + TPM_BN_free(cBignum); /* @6 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage19(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData) +{ + TPM_RESULT rc = 0; + unsigned char *r2 = NULL; /* freed @1 */ + TPM_BIGNUM r2Bignum = NULL; /* freed @2 */ + TPM_BIGNUM s2Bignum = NULL; /* freed @3 */ + TPM_BIGNUM cBignum = NULL; /* freed @4 */ + TPM_BIGNUM u0Bignum = NULL; /* freed @5 */ + + printf("TPM_DAAJoin_Stage19:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==19. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Obtain DAA_SIZE_r2 bytes using the MGF1 function and label them r2. "r2" || DAA_session -> + DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage19: Creating r2\n"); + rc = TPM_MGF1_GenerateArray(&r2, /* returned MGF1 array */ + DAA_SIZE_r2, /* size of Y */ + /* length of the entire seed */ + sizeof("r2") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r2") -1, "r2", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r2Bignum, r2, DAA_SIZE_r2); + } + /* e. Set s2 = r2 + (DAA_session -> DAA_digest)*( DAA_joinSession -> DAA_join_u0) mod + 2^DAA_power1 (Erase all but the lowest DAA_power1 bits of s2) */ + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage19: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* FIXME Set u0 = DAA_joinSession -> DAA_join_u0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage19: Creating u0 from DAA_joinSession -> DAA_join_u0\n"); + rc = TPM_bin2bn(&u0Bignum, + tpm_daa_session_data->DAA_joinSession.DAA_join_u0, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u0)); + } + /* s2 = (r2 + c * u0) mod_pow */ + if (rc == 0) { + rc = TPM_ComputeApBxC(&s2Bignum, /* result */ + r2Bignum, /* A */ + cBignum, /* B */ + u0Bignum); /* C */ + } + if (rc == 0) { + rc = TPM_BN_mask_bits(s2Bignum, DAA_power1); + } + /* f. set outputData = s2 */ + if (rc == 0) { + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + s2Bignum, 0); + } + /* insure that outputData is DAA_power1 bits */ + if (rc == 0) { + rc = TPM_SizedBuffer_ComputeEnlarge(outputData, DAA_power1 / 8); + } + /* g. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* h. return TPM_SUCCESS */ + free(r2); /* @1 */ + TPM_BN_free(r2Bignum); /* @2 */ + TPM_BN_free(s2Bignum); /* @3 */ + TPM_BN_free(cBignum); /* @4 */ + TPM_BN_free(u0Bignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage20(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData) +{ + TPM_RESULT rc = 0; + unsigned char *r2 = NULL; /* freed @1 */ + TPM_BIGNUM r2Bignum = NULL; /* freed @2 */ + TPM_BIGNUM s12Bignum = NULL; /* freed @3 */ + TPM_BIGNUM s12sBignum = NULL; /* freed @4 */ + TPM_BIGNUM cBignum = NULL; /* freed @5 */ + TPM_BIGNUM u0Bignum = NULL; /* freed @6 */ + + unsigned int numBytes; /* just for debug */ + + printf("TPM_DAAJoin_Stage20:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==20. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Obtain DAA_SIZE_r2 bytes using the MGF1 function and label them r2. "r2" || DAA_session + -> DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage20: Creating r2\n"); + rc = TPM_MGF1_GenerateArray(&r2, /* returned MGF1 array */ + DAA_SIZE_r2, /* size of Y */ + /* length of the entire seed */ + sizeof("r2") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r2") -1, "r2", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r2Bignum, r2, DAA_SIZE_r2); + } + /* e. Set s12 = r2 + (DAA_session -> DAA_digest)*( DAA_joinSession -> DAA_join_u0) */ + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage20: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* FIXME Set u0 = DAA_joinSession -> DAA_join_u0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage20: Creating u0 from DAA_joinSession -> DAA_join_u0\n"); + rc = TPM_bin2bn(&u0Bignum, + tpm_daa_session_data->DAA_joinSession.DAA_join_u0, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u0)); + } + /* s12 = (r2 + c * u0) mod_pow */ + if (rc == 0) { + rc = TPM_ComputeApBxC(&s12Bignum, /* result */ + r2Bignum, /* A */ + cBignum, /* B */ + u0Bignum); /* C */ + } + /* FIXME for debug */ + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, s12Bignum); + printf("TPM_DAAJoin_Stage20: e. s12 size %u\n", numBytes); + } + /* f. Shift s12 right by DAA_power1 bit (discard the lowest DAA_power1 bits). */ + if (rc == 0) { + rc = TPM_BN_rshift(&s12sBignum, s12Bignum, DAA_power1); /* s12 becomes s12s */ + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, s12sBignum); + printf("TPM_DAAJoin_Stage20: f. s12 size %u\n", numBytes); + } + /* g. Set DAA_session -> DAA_scratch = s12 */ + if (rc == 0) { + rc = TPM_ComputeDAAScratch(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + s12sBignum); + } + /* h. Set outputData = DAA_session -> DAA_digest */ + if (rc == 0) { + rc = TPM_SizedBuffer_Set(outputData, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_session.DAA_digest); + } + /* i. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* j. return TPM_SUCCESS */ + free(r2); /* @1 */ + TPM_BN_free(r2Bignum); /* @2 */ + TPM_BN_free(s12Bignum); /* @3 */ + TPM_BN_free(s12sBignum); /* @4 */ + TPM_BN_free(cBignum); /* @5 */ + TPM_BN_free(u0Bignum); /* @6 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage21(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData) +{ + TPM_RESULT rc = 0; + unsigned char *r3 = NULL; /* freed @1 */ + TPM_BIGNUM r3Bignum = NULL; /* freed @2 */ + TPM_BIGNUM s3Bignum = NULL; /* freed @3 */ + TPM_BIGNUM cBignum = NULL; /* freed @4 */ + TPM_BIGNUM u1Bignum = NULL; /* freed @5 */ + TPM_BIGNUM s12Bignum = NULL; /* freed @6 */ + + unsigned int numBytes; /* just for debug */ + + printf("TPM_DAAJoin_Stage21:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==21. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Obtain DAA_SIZE_r3 bytes using the MGF1 function and label them r3. "r3" || DAA_session + -> DAA_contextSeed) is the Z seed. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage21: Creating r3\n"); + rc = TPM_MGF1_GenerateArray(&r3, /* returned MGF1 array */ + DAA_SIZE_r3, /* size of r3 */ + /* length of the entire seed */ + sizeof("r3") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r3") -1, "r3", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r3Bignum, r3, DAA_SIZE_r3); + } + /* just for debug */ + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, r3Bignum); + printf("TPM_DAAJoin_Stage21: r3 size %u\n", numBytes); + } + /* e. Set s3 = r3 + (DAA_session -> DAA_digest)*( DAA_joinSession -> DAA_join_u1) + (DAA_session + -> DAA_scratch). */ + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage21: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* just for debug */ + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, cBignum); + printf("TPM_DAAJoin_Stage21: c size %u\n", numBytes); + } + /* FIXME Set u1 = DAA_joinSession -> DAA_join_u1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage21: Creating u1 from DAA_joinSession -> DAA_join_u1\n"); + rc = TPM_bin2bn(&u1Bignum, + tpm_daa_session_data->DAA_joinSession.DAA_join_u1, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u1)); + } + /* just for debug */ + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, u1Bignum); + printf("TPM_DAAJoin_Stage21: u1 size %u\n", numBytes); + } + /* FIXME Set s12 = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage21: Creating s12 from DAA_session -> DAA_scratch\n"); + rc = TPM_bin2bn(&s12Bignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, s12Bignum); + printf("TPM_DAAJoin_Stage21: s12 size %u\n", numBytes); + } + /* s3 = r3 + c * u1 + s12 */ + if (rc == 0) { + rc = TPM_ComputeApBxCpD(&s3Bignum, /* freed by caller */ + r3Bignum, /* A */ + cBignum, /* B */ + u1Bignum, /* C */ + s12Bignum); /* D */ + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, s3Bignum); + printf("TPM_DAAJoin_Stage21: s3 size %u\n", numBytes); + } + /* f. Set DAA_session -> DAA_scratch = NULL */ + if (rc == 0) { + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + } + /* g. set outputData = s3 */ + if (rc == 0) { + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + s3Bignum, 0); + } + /* h. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* i. return TPM_SUCCESS */ + free(r3); /* @1 */ + TPM_BN_free(r3Bignum); /* @2 */ + TPM_BN_free(s3Bignum); /* @3 */ + TPM_BN_free(cBignum); /* @4 */ + TPM_BN_free(u1Bignum); /* @5 */ + TPM_BN_free(s12Bignum); /* @6 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage22(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM v10Bignum = NULL; /* freed @1 */ + TPM_BIGNUM v10sBignum = NULL; /* freed @2 */ + TPM_BIGNUM u0Bignum = NULL; /* freed @3 */ + TPM_BIGNUM u2Bignum = NULL; /* freed @4 */ + TPM_BIGNUM v0Bignum = NULL; /* freed @5 */ + TPM_DAA_SENSITIVE tpm_daa_sensitive; + + unsigned int numBytes; /* just for debug */ + + printf("TPM_DAAJoin_Stage22:\n"); + TPM_DAASensitive_Init(&tpm_daa_sensitive); /* freed @6 */ + /* a. Verify that DAA_session ->DAA_stage==22. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Verify inputSize0 == DAA_SIZE_v0 and return error TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + if (inputData0->size != DAA_SIZE_v0) { + printf("TPM_DAAJoin_Stage22: Error, inputData0 size %u should be %u\n", + inputData0->size, DAA_SIZE_v0); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Set u2 = inputData0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage22: Creating u2\n"); + rc = TPM_bin2bn(&u2Bignum, inputData0->buffer, inputData0->size); + } + /* f. Set v0 = u2 + (DAA_joinSession -> DAA_join_u0) mod 2^DAA_power1 (Erase all but the lowest + DAA_power1 bits of v0). */ + /* FIXME Set u0 = DAA_joinSession -> DAA_join_u0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage22: Creating u0 from DAA_joinSession -> DAA_join_u0\n"); + rc = TPM_bin2bn(&u0Bignum, + tpm_daa_session_data->DAA_joinSession.DAA_join_u0, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u0)); + } + /* FIXME factor this? */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage22: Calculate v0\n"); + rc = TPM_BN_new(&v0Bignum); + } + /* v0 = u2 + u0 */ + if (rc == 0) { + rc = TPM_BN_add(v0Bignum, u2Bignum, u0Bignum); + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, v0Bignum); + printf("TPM_DAAJoin_Stage22: f. v0 size before mask %u\n", numBytes); + } + /* v0 = v0 mod 2^DAA_power1 */ + if (rc == 0) { + rc = TPM_BN_mask_bits(v0Bignum, DAA_power1); + } + if (rc == 0) { + rc = TPM_BN_num_bytes(&numBytes, v0Bignum); + printf("TPM_DAAJoin_Stage22: f. v0 size after mask %u\n", numBytes); + } + /* g. Set DAA_tpmSpecific -> DAA_digest_v0 = SHA-1(v0) */ + if (rc == 0) { + rc = TPM_SHA1_BignumGenerate(tpm_daa_session_data->DAA_tpmSpecific.DAA_digest_v0, + v0Bignum, + (DAA_power1 + 7) / 8); /* canonicalize the number of + bytes */ + } + /* h. Set v10 = u2 + (DAA_joinSession -> DAA_join_u0) in Z. Compute over the integers. + The computation is not reduced with a modulus. */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage22: Calculate v10\n"); + rc = TPM_BN_new(&v10Bignum); + } + /* v0 = u2 + u0 */ + if (rc == 0) { + rc = TPM_BN_add(v10Bignum, u2Bignum, u0Bignum); + } + /* i. Shift v10 right by DAA_power1 bits (erase the lowest DAA_power1 bits). */ + if (rc == 0) { + rc = TPM_BN_rshift(&v10sBignum, v10Bignum, DAA_power1); + } + /* j. Set DAA_session -> DAA_scratch = v10 */ + if (rc == 0) { + rc = TPM_ComputeDAAScratch(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + v10sBignum); + } + /* k. Set outputData */ + /* i. Fill in TPM_DAA_BLOB with a type of TPM_RT_DAA_V0 and encrypt the v0 parameters using + TPM_PERMANENT_DATA -> daaBlobKey */ + /* Create a TPM_DAA_SENSITIVE structure */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage22: Create TPM_DAA_SENSITIVE\n"); + /* Set TPM_DAA_SENSITIVE -> internalData to v0Bignum */ + rc = TPM_bn2binMalloc(&(tpm_daa_sensitive.internalData.buffer), + &(tpm_daa_sensitive.internalData.size), + v0Bignum, 0); + } + if (rc == 0) { + rc = TPM_ComputeEncrypt(outputData, + tpm_state, + &tpm_daa_sensitive, + TPM_RT_DAA_V0); + } + /* l. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* m. set DAA_session -> DAA_digestContext = SHA-1(DAA_tpmSpecific || DAA_joinSession) */ + if (rc == 0) { + rc = TPM_DAADigestContext_GenerateDigestJoin + (tpm_daa_session_data->DAA_session.DAA_digestContext, tpm_daa_session_data); + } + /* n. return TPM_SUCCESS */ + TPM_BN_free(v10Bignum); /* @1 */ + TPM_BN_free(v10sBignum); /* @2 */ + TPM_BN_free(u0Bignum); /* @3 */ + TPM_BN_free(u2Bignum); /* @4 */ + TPM_BN_free(v0Bignum); /* @5 */ + TPM_DAASensitive_Delete(&tpm_daa_sensitive); /* @6 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage23(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM u1Bignum = NULL; /* freed @1 */ + TPM_BIGNUM u3Bignum = NULL; /* freed @2 */ + TPM_BIGNUM v1Bignum = NULL; /* freed @3 */ + TPM_BIGNUM v10Bignum = NULL; /* freed @4 */ + TPM_DAA_SENSITIVE tpm_daa_sensitive; + + printf("TPM_DAAJoin_Stage23:\n"); + TPM_DAASensitive_Init(&tpm_daa_sensitive); /* freed @5 */ + /* a. Verify that DAA_session ->DAA_stage==23. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Verify inputSize0 == DAA_SIZE_v1 and return error TPM_DAA_INPUT_DATA0 on */ + /* mismatch */ + if (rc == 0) { + if (inputData0->size != DAA_SIZE_v1) { + printf("TPM_DAAJoin_Stage23: Error, inputData0 size %u should be %u\n", + inputData0->size, DAA_SIZE_v1); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Set u3 = inputData0 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage23: Creating u3\n"); + rc = TPM_bin2bn(&u3Bignum, inputData0->buffer, inputData0->size); + } + /* f. Set v1 = u3 + DAA_joinSession -> DAA_join_u1 + DAA_session -> DAA_scratch */ + /* FIXME Set u1 = DAA_joinSession -> DAA_join_u1 */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage23: Creating u1 from DAA_joinSession -> DAA_join_u1\n"); + rc = TPM_bin2bn(&u1Bignum, + tpm_daa_session_data->DAA_joinSession.DAA_join_u1, + sizeof(tpm_daa_session_data->DAA_joinSession.DAA_join_u1)); + } + /* FIXME Set v10 = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage23: Creating v10\n"); + rc = TPM_bin2bn(&v10Bignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + if (rc == 0) { + rc = TPM_BN_new(&v1Bignum); + } + /* f. Set v1 = u3 + u1 + v10 */ + if (rc == 0) { + rc = TPM_BN_add(v1Bignum, u3Bignum, u1Bignum); + } + if (rc == 0) { + rc = TPM_BN_add(v1Bignum, v1Bignum,v10Bignum); + } + /* g. Set DAA_tpmSpecific -> DAA_digest_v1 = SHA-1(v1) */ + if (rc == 0) { + rc = TPM_SHA1_BignumGenerate(tpm_daa_session_data->DAA_tpmSpecific.DAA_digest_v1, + v1Bignum, + DAA_SIZE_v1); /* canonicalize the number of bytes */ + } + /* h. Set outputData */ + /* i. Fill in TPM_DAA_BLOB with a type of TPM_RT_DAA_V1 and encrypt the v1 parameters using + TPM_PERMANENT_DATA -> daaBlobKey */ + /* Create a TPM_DAA_SENSITIVE structure */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage23: Create TPM_DAA_SENSITIVE\n"); + /* Set TPM_DAA_SENSITIVE -> internalData to v1Bignum */ + rc = TPM_bn2binMalloc(&(tpm_daa_sensitive.internalData.buffer), + &(tpm_daa_sensitive.internalData.size), + v1Bignum, 0); + } + if (rc == 0) { + rc = TPM_ComputeEncrypt(outputData, + tpm_state, + &tpm_daa_sensitive, + TPM_RT_DAA_V1); + } + + + /* i. Set DAA_session -> DAA_scratch = NULL */ + if (rc == 0) { + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + } + /* j. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* k. set DAA_session -> DAA_digestContext = SHA-1(DAA_tpmSpecific || DAA_joinSession) */ + if (rc == 0) { + rc = TPM_DAADigestContext_GenerateDigestJoin + (tpm_daa_session_data->DAA_session.DAA_digestContext, tpm_daa_session_data); + } + /* l. return TPM_SUCCESS */ + TPM_BN_free(u1Bignum); /* @1 */ + TPM_BN_free(u3Bignum); /* @2 */ + TPM_BN_free(v1Bignum); /* @3 */ + TPM_BN_free(v10Bignum); /* @4 */ + TPM_DAASensitive_Delete(&tpm_daa_sensitive); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAAJoin_Stage24(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData) +{ + TPM_RESULT rc = 0; + TPM_DAA_SENSITIVE tpm_daa_sensitive; + + printf("TPM_DAAJoin_Stage24:\n"); + TPM_DAASensitive_Init(&tpm_daa_sensitive); /* freed @1 */ + /* a. Verify that DAA_session ->DAA_stage==24. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) + and return error TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. set outputData = enc(DAA_tpmSpecific) using TPM_PERMANENT_DATA -> daaBlobKey */ + /* Create a TPM_DAA_SENSITIVE structure */ + if (rc == 0) { + printf("TPM_DAAJoin_Stage24 Create TPM_DAA_SENSITIVE\n"); + /* Set TPM_DAA_SENSITIVE -> internalData to DAA_tpmSpecific */ + rc = TPM_SizedBuffer_SetStructure(&(tpm_daa_sensitive.internalData), + &(tpm_daa_session_data->DAA_tpmSpecific), + (TPM_STORE_FUNCTION_T)TPM_DAATpm_Store); + } + if (rc == 0) { + rc = TPM_ComputeEncrypt(outputData, + tpm_state, + &tpm_daa_sensitive, + TPM_RT_DAA_TPM); + } + /* e. return TPM_SUCCESS */ + TPM_DAASensitive_Delete(&tpm_daa_sensitive); /* @2 */ + return rc; +} + +TPM_RESULT TPM_DAASign_Stage00(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA **tpm_daa_session_data, /* returns entry in + array */ + TPM_BOOL *daaHandleValid, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *stream; + uint32_t stream_size; + TPM_HANDLE daaHandle = 0; /* no preassigned handle */ + + printf("TPM_DAASign_Stage00:\n"); + /* a. Determine that sufficient resources are available to perform a TPM_DAA_Sign. */ + /* i. The TPM MUST support sufficient resources to perform one (1) + TPM_DAA_Join/TPM_DAA_Sign. The TPM MAY support addition TPM_DAA_Join/ TPM_DAA_Sign + sessions. */ + /* ii. The TPM may share internal resources between the DAA operations and other variable + resource requirements: */ + /* iii. If there are insufficient resources within the stored key pool (and one or more keys + need to be removed to permit the DAA operation to execute) return TPM_NOSPACE */ + /* iv. If there are insufficient resources within the stored session pool (and one or more + authorization or transport sessions need to be removed to permit the DAA operation to + execute), return TPM_RESOURCES. */ + if (rc == 0) { + rc = TPM_DaaSessions_GetNewHandle(tpm_daa_session_data, /* returns entry in array */ + &daaHandle, /* output */ + daaHandleValid, /* output */ + tpm_state->tpm_stclear_data.daaSessions); /* array */ + } + /* b. Set DAA_issuerSettings = inputData0 */ + if (rc == 0) { + stream = inputData0->buffer; + stream_size = inputData0->size; + rc = TPM_DAAIssuer_Load(&((*tpm_daa_session_data)->DAA_issuerSettings), + &stream, &stream_size); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* c. Verify that all fields in DAA_issuerSettings are present and return error + TPM_DAA_INPUT_DATA0 if not. */ + if (rc == 0) { + if (stream_size != 0) { + printf("TPM_DAASign_Stage00: Error, bad input0 size %u\n", inputData0->size); + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + /* d. set all fields in DAA_session = NULL */ + /* e. Assign new handle for session */ + /* NOTE Done by TPM_DaaSessions_GetNewHandle() */ + printf("TPM_DAASign_Stage00: handle %08x\n", (*tpm_daa_session_data)->daaHandle); + /* f. Set outputData to new handle */ + /* i. The handle in outputData is included the output HMAC. */ + rc = TPM_SizedBuffer_Append32(outputData, (*tpm_daa_session_data)->daaHandle); + } + /* g. set DAA_session -> DAA_stage = 1 */ + /* NOTE Done by common code */ + /* h. return TPM_SUCCESS */ + return rc; +} + +TPM_RESULT TPM_DAASign_Stage01(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + TPM_DAA_SENSITIVE tpm_daa_sensitive; + unsigned char *stream; + uint32_t stream_size; + + printf("TPM_DAASign_Stage01:\n"); + outputData = outputData; /* not used */ + TPM_DAASensitive_Init(&tpm_daa_sensitive); /* freed @1 */ + /* a. Verify that DAA_session ->DAA_stage==1. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Set DAA_tpmSpecific = unwrap(inputData0) using TPM_PERMANENT_DATA -> daaBlobKey */ + if (rc == 0) { + rc = TPM_ComputeDecrypt(&tpm_daa_sensitive, /* output */ + tpm_state, /* decryption and HMAC keys */ + inputData0, /* encrypted stream */ + TPM_RT_DAA_TPM); /* resourceType expected */ + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + stream = tpm_daa_sensitive.internalData.buffer; + stream_size = tpm_daa_sensitive.internalData.size; + rc = TPM_DAATpm_Load(&(tpm_daa_session_data->DAA_tpmSpecific), &stream, &stream_size); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* c. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + + /* d. set DAA_session -> DAA_digestContext = SHA-1(DAA_tpmSpecific) */ + if (rc == 0) { + rc = TPM_SHA1_GenerateStructure(tpm_daa_session_data->DAA_session.DAA_digestContext, + &(tpm_daa_session_data->DAA_tpmSpecific), + (TPM_STORE_FUNCTION_T)TPM_DAATpm_Store); + } + /* e set outputData = NULL */ + /* NOTE Done by caller */ + /* f. set DAA_session -> DAA_stage =2 */ + /* NOTE Done by common code */ + /* g. return TPM_SUCCESS */ + TPM_DAASensitive_Delete(&tpm_daa_sensitive); /* @1 */ + return rc; +} + +TPM_RESULT TPM_DAASign_Stage05(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + unsigned char *Y = NULL; /* freed @1 */ + TPM_BIGNUM yBignum = NULL; /* freed @2 */ + TPM_BIGNUM xBignum = NULL; /* freed @3 */ + TPM_BIGNUM nBignum = NULL; /* freed @4 */ + TPM_BIGNUM zBignum = NULL; /* freed @5 */ + + printf("TPM_DAASign_Stage05:\n"); + tpm_state = tpm_state; /* not used */ + /* a. Verify that DAA_session ->DAA_stage==5. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific) and return error + TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_generic_S1 = inputData0 */ + /* e. Verify that SHA-1(DAA_generic_S1) == DAA_issuerSettings -> DAA_digest_S1 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAASign_Stage05: Checking DAA_generic_S1\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_S1, /* expect */ + inputData0->size, inputData0->buffer, /* DAA_generic_S1 */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Set DAA_generic_n = inputData1 */ + /* g. Verify that SHA-1(DAA_generic_n) == DAA_issuerSettings -> DAA_digest_n and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + printf("TPM_DAASign_Stage05: Checking DAA_digest_n\n"); + rc = TPM_SHA1_Check(tpm_daa_session_data->DAA_issuerSettings.DAA_digest_n, /* expect */ + inputData1->size, inputData1->buffer, /* DAA_generic_n */ + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* h. Obtain DAA_SIZE_r4 bytes using the MGF1 function and label them Y. "r4" || DAA_session -> + DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAASign_Stage05: Creating Y\n"); + rc = TPM_MGF1_GenerateArray(&Y, /* returned MGF1 array */ + DAA_SIZE_r4, /* size of Y */ + /* length of the entire seed */ + sizeof("r4") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r4") -1, "r4", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&yBignum, Y, DAA_SIZE_r4); + } + /* i. Set X = DAA_generic_S1 */ + if (rc == 0) { + printf("TPM_DAASign_Stage05 Creating X\n"); + rc = TPM_bin2bn(&xBignum, inputData0->buffer, inputData0->size); + } + /* j. Set n = DAA_generic_n */ + if (rc == 0) { + printf("TPM_DAASign_Stage05: Creating n\n"); + rc = TPM_bin2bn(&nBignum, inputData1->buffer, inputData1->size); + } + /* k. Set Z = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAASign_Stage05: Creating Z\n"); + rc = TPM_bin2bn(&zBignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* l. Set DAA_session -> DAA_scratch = Z*(X^Y) mod n */ + if (rc == 0) { + rc = TPM_ComputeZxAexpPmodn(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + zBignum, /* Z */ + xBignum, /* A */ + yBignum, /* P */ + nBignum); /* N */ + } + /* m. set outputData = DAA_session -> DAA_scratch */ + if (rc == 0) { + rc = TPM_SizedBuffer_Set(outputData, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + tpm_daa_session_data->DAA_session.DAA_scratch); + } + /* n. set DAA_session -> DAA_scratch = NULL */ + if (rc == 0) { + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + } + /* o. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* p. return TPM_SUCCESS */ + free(Y); /* @1 */ + TPM_BN_free(yBignum); /* @2 */ + TPM_BN_free(xBignum); /* @3 */ + TPM_BN_free(nBignum); /* @4 */ + TPM_BN_free(zBignum); /* @5 */ + return rc; +} + +TPM_RESULT TPM_DAASign_Stage10(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0, + TPM_SIZED_BUFFER *inputData1) +{ + TPM_RESULT rc = 0; + unsigned char *stream; + uint32_t stream_size; + uint8_t selector; + TPM_BOOL parentPCRStatus; + TPM_KEY_HANDLE keyHandle; + TPM_KEY *identityKey = NULL; /* the key specified by keyHandle */ + + printf("TPM_DAASign_Stage10:\n"); + /* a. Verify that DAA_session ->DAA_stage==10. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific) and return error + TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Verify that inputSize0 == sizeOf(BYTE), and return error TPM_DAA_INPUT_DATA0 on + mismatch */ + /* e. Set selector = inputData0, verify that selector == 0 or 1, and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + stream = inputData0->buffer; + stream_size = inputData0->size; + rc = TPM_Load8(&selector, &stream, &stream_size); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + if (stream_size != 0) { + printf("TPM_DAASign_Stage10: Error, bad input0 size %u\n", inputData0->size); + rc = TPM_DAA_INPUT_DATA0; + } + } + if (rc == 0) { + printf("TPM_DAASign_Stage10: selector %u\n", selector); + switch (selector) { + case 1: + /* f. If selector == 1, verify that inputSize1 == sizeOf(TPM_DIGEST), and return error + TPM_DAA_INPUT_DATA1 on mismatch */ + if (rc == 0) { + if (inputData1->size != TPM_DIGEST_SIZE) { + printf("TPM_DAASign_Stage10: Error, bad input1 size %u\n", inputData1->size); + rc = TPM_DAA_INPUT_DATA1; + } + } + /* g. Set DAA_session -> DAA_digest to SHA-1 (DAA_session -> DAA_digest || 1 || + inputData1) */ + if (rc == 0) { + rc = TPM_SHA1(tpm_daa_session_data->DAA_session.DAA_digest, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_session.DAA_digest, + 1, &selector , + inputData1->size, inputData1->buffer, + 0, NULL); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + break; + case 0: + /* h. If selector == 0, verify that inputData1 is a handle to a TPM identity key (AIK), + and return error TPM_DAA_INPUT_DATA1 on mismatch */ + /* get the key handle */ + if (rc == 0) { + stream = inputData1->buffer; + stream_size = inputData1->size; + rc = TPM_Load32(&keyHandle, &stream, &stream_size); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* validate inputData1 */ + if (rc == 0) { + if (stream_size != 0) { + printf("TPM_DAASign_Stage10: Error, bad input1 size %u\n", inputData1->size); + rc = TPM_DAA_INPUT_DATA1; + } + } + /* get the key */ + if (rc == 0) { + rc = TPM_KeyHandleEntries_GetKey(&identityKey, &parentPCRStatus, + tpm_state, keyHandle, + TRUE, /* read only */ + FALSE, /* do not ignore PCRs */ + FALSE); /* cannot use EK */ + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA1; + } + } + /* validate that it's an AIK */ + if (rc == 0) { + if (identityKey->keyUsage != TPM_KEY_IDENTITY) { + printf("TPM_DAASign_Stage10: Error, " + "key keyUsage %04hx must be TPM_KEY_IDENTITY\n", identityKey->keyUsage); + rc = TPM_DAA_INPUT_DATA1; + } + } + /* i. Set DAA_session -> DAA_digest to SHA-1 (DAA_session -> DAA_digest || 0 || n2) + where n2 is the modulus of the AIK */ + if (rc == 0) { + rc = TPM_SHA1(tpm_daa_session_data->DAA_session.DAA_digest, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_session.DAA_digest, + 1, &selector, + identityKey->pubKey.size, identityKey->pubKey.buffer, + 0, NULL); + } + break; + default: + printf("TPM_DAASign_Stage10: Error, bad selector %u\n", selector); + rc = TPM_DAA_INPUT_DATA0; + break; + } + } + /* j. Set outputData = DAA_session -> DAA_digest */ + if (rc == 0) { + rc = TPM_SizedBuffer_Set(outputData, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_session.DAA_digest); + } + /* k. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* l. return TPM_SUCCESS. */ + return rc; +} + +TPM_RESULT TPM_DAASign_Stage13(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *r2 = NULL; /* freed @1 */ + TPM_BIGNUM r2Bignum = NULL; /* freed @2 */ + TPM_BIGNUM s2Bignum = NULL; /* freed @3 */ + TPM_BIGNUM cBignum = NULL; /* freed @4 */ + TPM_BIGNUM v0Bignum = NULL; /* freed @5 */ + TPM_DAA_SENSITIVE tpm_daa_sensitive; + + printf("TPM_DAASign_Stage13:\n"); + TPM_DAASensitive_Init(&tpm_daa_sensitive); /* freed @6 */ + /* a. Verify that DAA_session ->DAA_stage==13. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific) and return error + TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_private_v0= unwrap(inputData0) using TPM_PERMANENT_DATA -> daaBlobKey */ + if (rc == 0) { + printf("TPM_DAASign_Stage13: unwrapping to v0\n"); + rc = TPM_ComputeDecrypt(&tpm_daa_sensitive, /* output */ + tpm_state, /* decryption and HMAC keys */ + inputData0, /* encrypted stream */ + TPM_RT_DAA_V0); /* resourceType expected */ + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Verify that SHA-1(DAA_private_v0) == DAA_tpmSpecific -> DAA_digest_v0 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAASign_Stage13: Checking v0\n"); + rc = TPM_SHA1_SizedBufferCheck(tpm_daa_session_data->DAA_tpmSpecific.DAA_digest_v0, + &(tpm_daa_sensitive.internalData), + (DAA_power1 + 7) / 8); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Obtain DAA_SIZE_r2 bytes from the MGF1 function and label them r2. "r2" || DAA_session -> + DAA_contextSeed) is the Z seed. */ + if (rc == 0) { + printf("TPM_DAASign_Stage13 Creating r2\n"); + rc = TPM_MGF1_GenerateArray(&r2, /* returned MGF1 array */ + DAA_SIZE_r2, /* size of Y */ + /* length of the entire seed */ + sizeof("r2") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r2") -1, "r2", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r2Bignum, r2, DAA_SIZE_r2); + } + /* g. Set s2 = r2 + (DAA_session -> DAA_digest)*( DAA_private_v0) mod 2^DAA_power1 */ + /* (erase all but the lowest DAA_power1 bits of s2) */ + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAASign_Stage13: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* FIXME Set v0 = DAA_private_v0 */ + if (rc == 0) { + rc = TPM_bin2bn(&v0Bignum, + tpm_daa_sensitive.internalData.buffer, + tpm_daa_sensitive.internalData.size); + } + /* s2 = r2 + c * v0 mod 2^DAA_power1 */ + if (rc == 0) { + rc = TPM_ComputeApBxC(&s2Bignum, /* result */ + r2Bignum, /* A */ + cBignum, /* B */ + v0Bignum); /* C */ + } + if (rc == 0) { + rc = TPM_BN_mask_bits(s2Bignum, DAA_power1); + } + /* h. set outputData = s2 */ + if (rc == 0) { + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + s2Bignum, 0); + } + /* i. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* j. return TPM_SUCCESS */ + free(r2); /* @1 */ + TPM_BN_free(r2Bignum); /* @2 */ + TPM_BN_free(s2Bignum); /* @3 */ + TPM_BN_free(cBignum); /* @4 */ + TPM_BN_free(v0Bignum); /* @5 */ + TPM_DAASensitive_Delete(&tpm_daa_sensitive); /* @6 */ + return rc; +} + +TPM_RESULT TPM_DAASign_Stage14(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *r2 = NULL; /* freed @1 */ + TPM_BIGNUM r2Bignum = NULL; /* freed @2 */ + TPM_BIGNUM s12Bignum = NULL; /* freed @3 */ + TPM_BIGNUM s12sBignum = NULL; /* freed @4 */ + TPM_BIGNUM cBignum = NULL; /* freed @5 */ + TPM_BIGNUM v0Bignum = NULL; /* freed @6 */ + TPM_DAA_SENSITIVE tpm_daa_sensitive; + + printf("TPM_DAASign_Stage14:\n"); + outputData = outputData; /* not used */ + TPM_DAASensitive_Init(&tpm_daa_sensitive); /* freed @7 */ + /* a. Verify that DAA_session ->DAA_stage==14. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific) and return error + TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_private_v0= unwrap(inputData0) using TPM_PERMANENT_DATA -> daaBlobKey */ + if (rc == 0) { + rc = TPM_ComputeDecrypt(&tpm_daa_sensitive, /* output */ + tpm_state, /* decryption and HMAC keys */ + inputData0, /* encrypted stream */ + TPM_RT_DAA_V0); /* resourceType expected */ + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Verify that SHA-1(DAA_private_v0) == DAA_tpmSpecific -> DAA_digest_v0 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAASign_Stage14: Checking v0\n"); + rc = TPM_SHA1_SizedBufferCheck(tpm_daa_session_data->DAA_tpmSpecific.DAA_digest_v0, + &(tpm_daa_sensitive.internalData), + (DAA_power1 + 7) / 8); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Obtain DAA_SIZE_r2 bytes from the MGF1 function and label them r2. "r2" || DAA_session -> + DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAASign_Stage14: Creating r2\n"); + rc = TPM_MGF1_GenerateArray(&r2, /* returned MGF1 array */ + DAA_SIZE_r2, /* size of Y */ + /* length of the entire seed */ + sizeof("r2") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r2") -1, "r2", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r2Bignum, r2, DAA_SIZE_r2); + } + /* g. Set s12 = r2 + (DAA_session -> DAA_digest)*(DAA_private_v0). */ + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAASign_Stage14: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* FIXME Set v0 = DAA_private_v0 */ + if (rc == 0) { + rc = TPM_bin2bn(&v0Bignum, + tpm_daa_sensitive.internalData.buffer, + tpm_daa_sensitive.internalData.size); + } + /* s12 = r2 + c * v0 */ + if (rc == 0) { + rc = TPM_ComputeApBxC(&s12Bignum, /* result */ + r2Bignum, /* A */ + cBignum, /* B */ + v0Bignum); /* C */ + } + /* h. Shift s12 right by DAA_power1 bits (erase the lowest DAA_power1 bits). */ + if (rc == 0) { + rc = TPM_BN_rshift(&s12sBignum, s12Bignum, DAA_power1); /* f becomes f1 */ + } + /* i. Set DAA_session -> DAA_scratch = s12 */ + if (rc == 0) { + rc = TPM_ComputeDAAScratch(tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch), + s12sBignum); + } + /* j. set outputData = NULL */ + /* NOTE Done by caller */ + /* k. increment DAA_session -> DAA_stage by 1 */ + /* NOTE Done by common code */ + /* l. return TPM_SUCCESS */ + free(r2); /* @1 */ + TPM_BN_free(r2Bignum); /* @2 */ + TPM_BN_free(s12Bignum); /* @3 */ + TPM_BN_free(s12sBignum); /* @4 */ + TPM_BN_free(cBignum); /* @5 */ + TPM_BN_free(v0Bignum); /* @6 */ + TPM_DAASensitive_Delete(&tpm_daa_sensitive); /* @7 */ + return rc; +} + +TPM_RESULT TPM_DAASign_Stage15(tpm_state_t *tpm_state, + TPM_DAA_SESSION_DATA *tpm_daa_session_data, + TPM_SIZED_BUFFER *outputData, + TPM_SIZED_BUFFER *inputData0) +{ + TPM_RESULT rc = 0; + unsigned char *r4 = NULL; /* freed @1 */ + TPM_BIGNUM r4Bignum = NULL; /* freed @2 */ + TPM_BIGNUM s3Bignum = NULL; /* freed @3 */ + TPM_BIGNUM cBignum = NULL; /* freed @4 */ + TPM_BIGNUM v1Bignum = NULL; /* freed @5 */ + TPM_BIGNUM s12Bignum = NULL; /* freed @6 */ + TPM_DAA_SENSITIVE tpm_daa_sensitive; + + printf("TPM_DAASign_Stage15:\n"); + TPM_DAASensitive_Init(&tpm_daa_sensitive); /* freed @7 */ + /* a. Verify that DAA_session ->DAA_stage==15. Return TPM_DAA_STAGE and flush handle on + mismatch */ + /* NOTE Done by common code */ + /* b. Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return + error TPM_DAA_ISSUER_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* c. Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific) and return error + TPM_DAA_TPM_SETTINGS on mismatch */ + /* NOTE Done by common code */ + /* d. Set DAA_private_v1 = unwrap(inputData0) using TPM_PERMANENT_DATA -> daaBlobKey */ + if (rc == 0) { + rc = TPM_ComputeDecrypt(&tpm_daa_sensitive, /* output */ + tpm_state, /* decryption and HMAC keys */ + inputData0, /* encrypted stream */ + TPM_RT_DAA_V1); /* resourceType expected */ + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* e. Verify that SHA-1(DAA_private_v1) == DAA_tpmSpecific -> DAA_digest_v1 and return error + TPM_DAA_INPUT_DATA0 on mismatch */ + if (rc == 0) { + printf("TPM_DAASign_Stage15: Checking v1\n"); + rc = TPM_SHA1_SizedBufferCheck(tpm_daa_session_data->DAA_tpmSpecific.DAA_digest_v1, + &(tpm_daa_sensitive.internalData), + DAA_SIZE_v1); + if (rc != 0) { + rc = TPM_DAA_INPUT_DATA0; + } + } + /* f. Obtain DAA_SIZE_r4 bytes from the MGF1 function and label them r4. "r4" || DAA_session -> + DAA_contextSeed is the Z seed. */ + if (rc == 0) { + printf("TPM_DAASign_Stage15: Creating r4\n"); + rc = TPM_MGF1_GenerateArray(&r4, /* returned MGF1 array */ + DAA_SIZE_r4, /* size of Y */ + /* length of the entire seed */ + sizeof("r4") -1 + + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + sizeof("r4") -1, "r4", + sizeof(tpm_daa_session_data->DAA_session.DAA_contextSeed), + tpm_daa_session_data->DAA_session.DAA_contextSeed, + 0, NULL); + } + if (rc == 0) { + rc = TPM_bin2bn(&r4Bignum, r4, DAA_SIZE_r4); + } + /* g. Set s3 = r4 + (DAA_session -> DAA_digest)*(DAA_private_v1) + (DAA_session -> + DAA_scratch). */ + /* FIXME Set c = DAA_session -> DAA_digest */ + if (rc == 0) { + printf("TPM_DAASign_Stage15: Creating c from DAA_session -> DAA_digest\n"); + rc = TPM_bin2bn(&cBignum, tpm_daa_session_data->DAA_session.DAA_digest, TPM_DIGEST_SIZE); + } + /* FIXME Set v1 = DAA_private_v1 */ + if (rc == 0) { + rc = TPM_bin2bn(&v1Bignum, + tpm_daa_sensitive.internalData.buffer, + tpm_daa_sensitive.internalData.size); + } + /* FIXME Set s12 = DAA_session -> DAA_scratch */ + if (rc == 0) { + printf("TPM_DAASign_Stage15: Creating s12 from DAA_session -> DAA_scratch\n"); + rc = TPM_bin2bn(&s12Bignum, + tpm_daa_session_data->DAA_session.DAA_scratch, + sizeof(tpm_daa_session_data->DAA_session.DAA_scratch)); + } + /* s3 = r4 + c * v1 + s12 */ + if (rc == 0) { + rc = TPM_ComputeApBxCpD(&s3Bignum, /* freed by caller */ + r4Bignum, /* A */ + cBignum, /* B */ + v1Bignum, /* C */ + s12Bignum); /* D */ + } + /* h. Set DAA_session -> DAA_scratch = NULL */ + if (rc == 0) { + tpm_daa_session_data->DAA_session.DAA_scratch_null = TRUE; + } + /* i. set outputData = s3 */ + if (rc == 0) { + rc = TPM_bn2binMalloc(&(outputData->buffer), + &(outputData->size), + s3Bignum, 0); + } + /* j. Terminate the DAA session and all resources associated with the DAA sign session + handle. */ + /* NOTE Done by caller */ + /* k. return TPM_SUCCESS */ + free(r4); /* @1 */ + TPM_BN_free(r4Bignum); /* @2 */ + TPM_BN_free(s3Bignum); /* @3 */ + TPM_BN_free(cBignum); /* @4 */ + TPM_BN_free(v1Bignum); /* @5 */ + TPM_BN_free(s12Bignum); /* @6 */ + TPM_DAASensitive_Delete(&tpm_daa_sensitive); /* @7 */ + return rc; +} + +/* + Stage Common Code +*/ + +/* TPM_DAADigestContext_GenerateDigestJoin() sets tpm_digest to SHA-1(DAA_tpmSpecific || + DAA_joinSession)) +*/ + +TPM_RESULT TPM_DAADigestContext_GenerateDigestJoin(TPM_DIGEST tpm_digest, + TPM_DAA_SESSION_DATA *tpm_daa_session_data) +{ + TPM_RESULT rc = 0; + TPM_STORE_BUFFER sbuffer; /* TPM_STORED_DATA serialization */ + + printf(" TPM_DAADigestContext_GenerateDigestJoin:\n"); + TPM_Sbuffer_Init(&sbuffer); /* freed @1 */ + /* serialize DAA_tpmSpecific */ + if (rc == 0) { + rc = TPM_DAATpm_Store(&sbuffer, &(tpm_daa_session_data->DAA_tpmSpecific)); + } + /* serialize DAA_joinSession */ + if (rc == 0) { + rc = TPM_DAAJoindata_Store(&sbuffer, &(tpm_daa_session_data->DAA_joinSession)); + } + /* calculate and return the digest */ + if (rc == 0) { + rc = TPM_SHA1Sbuffer(tpm_digest, &sbuffer); + } + TPM_Sbuffer_Delete(&sbuffer); /* @1 */ + return rc; +} + +/* TPM_DAADigestContext_CheckDigestJoin() verifies that DAA_session -> DAA_digestContext == + SHA-1(DAA_tpmSpecific || DAA_joinSession). + + Returns TPM_DAA_TPM_SETTINGS on mismatch +*/ + +TPM_RESULT TPM_DAADigestContext_CheckDigestJoin(TPM_DAA_SESSION_DATA *tpm_daa_session_data) +{ + TPM_RESULT rc = 0; + TPM_DIGEST tpm_digest; /* actual digest */ + + printf(" TPM_DAADigestContext_CheckDigestJoin:\n"); + if (rc == 0) { + rc = TPM_DAADigestContext_GenerateDigestJoin(tpm_digest, tpm_daa_session_data); + } + if (rc == 0) { + rc = TPM_Digest_Compare(tpm_digest, tpm_daa_session_data->DAA_session.DAA_digestContext); + if (rc != 0) { + rc = TPM_DAA_TPM_SETTINGS; + } + } + return rc; +} + +/* TPM_ComputeF() computes the value F common to stages 4.j., 5.j., 14.f., 17.e., 18.e. + + j. Set f = SHA1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 0) || + SHA1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 1 ) + mod DAA_issuerSettings -> DAA_generic_q +*/ + +TPM_RESULT TPM_ComputeF(TPM_BIGNUM *fBignum, /* freed by caller */ + TPM_DAA_SESSION_DATA *tpm_daa_session_data) +{ + TPM_RESULT rc = 0; + BYTE nZero = 0; + BYTE nOne = 1; + uint32_t nCount; /* DAA_count in nbo */ + TPM_DIGEST digest0; /* first SHA1 calculation */ + TPM_DIGEST digest1; /* second SHA1 calculation */ + TPM_BIGNUM dividend; /* digest0 || digest1 as a BIGNUM */ + TPM_BIGNUM modulus; /* DAA_generic_q as a BIGNUM */ + + printf(" TPM_ComputeF:\n"); + modulus = NULL; /* freed @1 */ + dividend = NULL; /* freed @2 */ + if (rc == 0) { + rc = TPM_BN_new(fBignum); + } + /* SHA1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 0) */ + if (rc == 0) { + printf(" TPM_ComputeF: Calculate digest0\n"); + nCount = htonl(tpm_daa_session_data->DAA_tpmSpecific.DAA_count); + rc = TPM_SHA1(digest0, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_tpmSpecific.DAA_rekey, + sizeof(uint32_t), &nCount, + sizeof(BYTE), &nZero, + 0, NULL); + } + /* SHA1(DAA_tpmSpecific -> DAA_rekey || DAA_tpmSpecific -> DAA_count || 1 ) */ + if (rc == 0) { + printf(" TPM_ComputeF: Calculate digest1\n"); + rc = TPM_SHA1(digest1, + TPM_DIGEST_SIZE, tpm_daa_session_data->DAA_tpmSpecific.DAA_rekey, + sizeof(uint32_t), &nCount, + sizeof(BYTE), &nOne, + 0, NULL); + } + /* Construct digest0 || digest1 as a positive BIGNUM */ + if (rc == 0) { + rc = TPM_2bin2bn(÷nd, + digest0, TPM_DIGEST_SIZE, + digest1, TPM_DIGEST_SIZE); + } + /* DAA_generic_q as a positive BIGNUM */ + if (rc == 0) { + rc = TPM_bin2bn(&modulus, + tpm_daa_session_data->DAA_issuerSettings.DAA_generic_q, + sizeof(tpm_daa_session_data->DAA_issuerSettings.DAA_generic_q)); + } + /* digest mod DAA_generic_q */ + if (rc == 0) { + rc = TPM_BN_mod(*fBignum, dividend, modulus); + } + TPM_BN_free(modulus); /* @1 */ + TPM_BN_free(dividend); /* @2 */ + return rc; +} + +/* TPM_ComputeAexpPmodn() performs R = (A ^ P) mod n. + + rBignum is new'ed by this function and must be freed by the caller + + If DAA_scratch is not NULL, r is returned in DAA_scratch. +*/ + +TPM_RESULT TPM_ComputeAexpPmodn(BYTE *DAA_scratch, + uint32_t DAA_scratch_size, + TPM_BIGNUM *rBignum, /* freed by caller */ + TPM_BIGNUM aBignum, + TPM_BIGNUM pBignum, + TPM_BIGNUM nBignum) +{ + TPM_RESULT rc = 0; + + printf(" TPM_ComputeAexpPmodn:\n"); + if (rc == 0) { + rc = TPM_BN_new(rBignum); + } + if (rc == 0) { + rc = TPM_BN_mod_exp(*rBignum, aBignum, pBignum, nBignum); + } + /* if the result should be returned in DAA_scratch */ + if ((rc == 0) && (DAA_scratch != NULL)) { + /* store the result in DAA_scratch */ + rc = TPM_ComputeDAAScratch(DAA_scratch, DAA_scratch_size, *rBignum); + } + return rc; +} + +/* TPM_ComputeZxAexpPmodn() performs DAA_scratch = Z * (A ^ P) mod n. + +*/ + +TPM_RESULT TPM_ComputeZxAexpPmodn(BYTE *DAA_scratch, + uint32_t DAA_scratch_size, + TPM_BIGNUM zBignum, + TPM_BIGNUM aBignum, + TPM_BIGNUM pBignum, + TPM_BIGNUM nBignum) +{ + TPM_RESULT rc = 0; + TPM_BIGNUM rBignum = NULL; /* freed @1 */ + + printf(" TPM_ComputeZxAexpPmodn:\n"); + if (rc == 0) { + printf(" TPM_ComputeZxAexpPmodn: Calculate R = A ^ P mod n\n"); + rc = TPM_ComputeAexpPmodn(NULL, /* DAA_scratch */ + 0, + &rBignum, /* R */ + aBignum, /* A */ + pBignum, + nBignum); + } + if (rc == 0) { + printf(" TPM_ComputeZxAexpPmodn: Calculate R = Z * R mod n\n"); + rc = TPM_BN_mod_mul(rBignum, zBignum, rBignum, nBignum); + } + /* store the result in DAA_scratch */ + if (rc == 0) { + rc = TPM_ComputeDAAScratch(DAA_scratch, DAA_scratch_size, rBignum); + } + TPM_BN_free(rBignum); /* @1 */ + return rc; +} + +/* TPM_ComputeApBmodn() performs R = A + B mod n + +*/ + +TPM_RESULT TPM_ComputeApBmodn(TPM_BIGNUM *rBignum, /* freed by caller */ + TPM_BIGNUM aBignum, + TPM_BIGNUM bBignum, + TPM_BIGNUM nBignum) +{ + TPM_RESULT rc = 0; + + printf(" TPM_ComputeApBmodn:\n"); + if (rc == 0) { + rc = TPM_BN_new(rBignum); /* freed by caller */ + } + if (rc == 0) { + rc = TPM_BN_mod_add(*rBignum, aBignum, bBignum, nBignum); + } + return rc; +} + +/* TPM_ComputeApBxC() performs R = A + B * C + +*/ + +TPM_RESULT TPM_ComputeApBxC(TPM_BIGNUM *rBignum, /* freed by caller */ + TPM_BIGNUM aBignum, + TPM_BIGNUM bBignum, + TPM_BIGNUM cBignum) +{ + TPM_RESULT rc = 0; + + printf(" TPM_ComputeApBxC:\n"); + if (rc == 0) { + rc = TPM_BN_new(rBignum); /* freed by caller */ + } + /* R = B * C */ + if (rc == 0) { + rc = TPM_BN_mul(*rBignum, bBignum, cBignum); + } + /* R = R + A */ + if (rc == 0) { + rc = TPM_BN_add(*rBignum, *rBignum, aBignum); + } + return rc; +} + +/* TPM_ComputeApBxCpD() performs R = A + B * C + D + +*/ + +TPM_RESULT TPM_ComputeApBxCpD(TPM_BIGNUM *rBignum, /* freed by caller */ + TPM_BIGNUM aBignum, + TPM_BIGNUM bBignum, + TPM_BIGNUM cBignum, + TPM_BIGNUM dBignum) +{ + TPM_RESULT rc = 0; + printf(" TPM_ComputeApBxCpD:\n"); + /* R = A + B * C */ + if (rc == 0) { + rc = TPM_ComputeApBxC(rBignum, /* freed by caller */ + aBignum, + bBignum, + cBignum); + } + /* R = R + D */ + if (rc == 0) { + rc = TPM_BN_add(*rBignum, *rBignum, dBignum); + } + return rc; +} + +/* TPM_ComputeDAAScratch() stores 'bn' in DAA_scratch + +*/ + +TPM_RESULT TPM_ComputeDAAScratch(BYTE *DAA_scratch, + uint32_t DAA_scratch_size, + TPM_BIGNUM bn) +{ + TPM_RESULT rc = 0; + + printf(" TPM_ComputeDAAScratch:\n"); + if (rc == 0) { + rc = TPM_bn2binArray(DAA_scratch, DAA_scratch_size, bn); + } + return rc; +} + +/* TPM_ComputeEnlarge() creates a buffer of size 'outSize' + + It copies 'outSize - inSize' zero bytes and then appends 'in' + + 'out' must be freed by the caller +*/ + +TPM_RESULT TPM_ComputeEnlarge(unsigned char **out, /* freed by caller */ + uint32_t outSize, + unsigned char *in, + uint32_t inSize) +{ + TPM_RESULT rc = 0; + + if (rc == 0) { + if (outSize <= inSize) { + printf("TPM_ComputeEnlarge: Error (fatal), inSize %u outSize %u\n", inSize, outSize); + rc = TPM_FAIL; + } + } + if (rc == 0) { + rc = TPM_Malloc(out, outSize); + } + if (rc == 0) { + memset(*out, 0, outSize - inSize); /* zero left bytes */ + memcpy(*out + outSize - inSize, in, inSize); /* copy right bytes */ + } + return rc; +} + +/* TPM_SizedBuffer_ComputeEnlarge() forces 'tpm_sized_buffer' to be 'size' bytes in length. + + If generally useful, this function should be moved to tpm_sizedbuffer.c +*/ + +TPM_RESULT TPM_SizedBuffer_ComputeEnlarge(TPM_SIZED_BUFFER *tpm_sized_buffer, uint32_t size) +{ + TPM_RESULT rc = 0; + unsigned char *newPtr; /* new buffer, enlarged */ + + newPtr = NULL; /* freed by caller */ + /* if tpm_sized_buffer needs to be enlarged */ + if (tpm_sized_buffer->size != size) { + if (rc == 0) { + /* copy the TPM_SIZED_BUFFER data. enlarged, to newPtr */ + rc = TPM_ComputeEnlarge(&newPtr, size, /* output buffer */ + tpm_sized_buffer->buffer, + tpm_sized_buffer->size); + } + if (rc == 0) { + /* after the copy, the old buffer is no longer needed */ + free(tpm_sized_buffer->buffer); + /* assign the with the enlarged buffer to the TPM_SIZED_BUFFER */ + tpm_sized_buffer->buffer = newPtr; + /* update size */ + tpm_sized_buffer->size = size; + } + } + return rc; +} + +/* TPM_ComputeEncrypt() does join steps common to encrypting output data. + + It serializes the TPM_DAA_SENSITIVE, encrypts it to TPM_DAA_BLOB ->sensitiveData, adds the + resourceType, generates the TPM_DAA_BLOB -> blobIntegrity HMAC using daaProof, and serializes the + result to outputData. +*/ + +TPM_RESULT TPM_ComputeEncrypt(TPM_SIZED_BUFFER *outputData, + tpm_state_t *tpm_state, + TPM_DAA_SENSITIVE *tpm_daa_sensitive, + TPM_RESOURCE_TYPE resourceType) +{ + TPM_RESULT rc = 0; + TPM_DAA_BLOB tpm_daa_blob; + TPM_STORE_BUFFER daaSensitiveSbuffer; + + printf(" TPM_ComputeEncrypt:\n"); + TPM_DAABlob_Init(&tpm_daa_blob); /* freed @1 */ + TPM_Sbuffer_Init(&daaSensitiveSbuffer); /* freed @2 */ + + /* serialize the TPM_DAA_SENSITIVE */ + if (rc == 0) { + rc = TPM_DAASensitive_Store(&daaSensitiveSbuffer, tpm_daa_sensitive); + } + /* Create a TPM_DAA_BLOB structure */ + if (rc == 0) { + printf(" TPM_ComputeEncrypt: Create TPM_DAA_BLOB\n"); + tpm_daa_blob.resourceType = resourceType; + /* Set TPM_DAA_BLOB -> sensitiveData to the encryption of serialized TPM_DAA_SENSITIVE */ + rc = TPM_SymmetricKeyData_EncryptSbuffer + (&(tpm_daa_blob.sensitiveData), /* output buffer */ + &daaSensitiveSbuffer, /* input buffer */ + tpm_state->tpm_permanent_data.daaBlobKey); /* key */ + } + /* set TPM_DAA_BLOB -> blobIntegrity to the HMAC of TPM_DAA_BLOB using daaProof as the secret */ + if (rc == 0) { + rc = TPM_HMAC_GenerateStructure(tpm_daa_blob.blobIntegrity, /* HMAC */ + tpm_state->tpm_permanent_data.daaProof, /* HMAC key */ + &tpm_daa_blob, /* structure */ + (TPM_STORE_FUNCTION_T)TPM_DAABlob_Store); /* store + function */ + } + /* ii. set outputData to the encrypted TPM_DAA_BLOB */ + if (rc == 0) { + rc = TPM_SizedBuffer_SetStructure(outputData, &tpm_daa_blob, + (TPM_STORE_FUNCTION_T )TPM_DAABlob_Store); + } + TPM_DAABlob_Delete(&tpm_daa_blob); /* @1 */ + TPM_Sbuffer_Delete(&daaSensitiveSbuffer); /* @2 */ + return rc; +} + +/* TPM_ComputeDecrypt() does sign steps common to decrypting input data + + It deserializes 'inputData" to a TPM_DAA_BLOB, and validates the resourceType and blobIntegrity + HMAC using daaProof. It decrypts TPM_DAA_BLOB ->sensitiveData and deserializes it to a + TPM_DAA_SENSITIVE. + + tpm_daa_sensitive must be deleted by the caller +*/ + +TPM_RESULT TPM_ComputeDecrypt(TPM_DAA_SENSITIVE *tpm_daa_sensitive, + tpm_state_t *tpm_state, + TPM_SIZED_BUFFER *inputData, + TPM_RESOURCE_TYPE resourceType) + +{ + TPM_RESULT rc = 0; + TPM_DAA_BLOB tpm_daa_blob; + unsigned char *stream; + uint32_t stream_size; + unsigned char *sensitiveStream; + uint32_t sensitiveStreamSize; + + printf(" TPM_ComputeDecrypt:\n"); + TPM_DAABlob_Init(&tpm_daa_blob); /* freed @1 */ + sensitiveStream = NULL; /* freed @2 */ + /* deserialize inputData to a TPM_DAA_BLOB */ + if (rc == 0) { + stream = inputData->buffer; + stream_size = inputData->size; + rc = TPM_DAABlob_Load(&tpm_daa_blob, &stream, &stream_size); + } + if (rc == 0) { + if (stream_size != 0) { + printf("TPM_ComputeDecrypt: Error, bad blob input size %u\n", inputData->size); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* check blobIntegrity */ + if (rc == 0) { + rc = TPM_HMAC_CheckStructure(tpm_state->tpm_permanent_data.daaProof, /* HMAC key */ + &tpm_daa_blob, /* structure */ + tpm_daa_blob.blobIntegrity, /* expected */ + (TPM_STORE_FUNCTION_T)TPM_DAABlob_Store, /* store function */ + TPM_DAA_INPUT_DATA0); /* error code */ + } + /* check resourceType */ + if (rc == 0) { + if (tpm_daa_blob.resourceType != resourceType) { + printf("TPM_ComputeDecrypt: Error, resourceType %08x\n", tpm_daa_blob.resourceType); + rc = TPM_DAA_INPUT_DATA0; + } + } + /* decrypt the TPM_DAA_BLOB -> sensitiveData */ + if (rc == 0) { + rc = TPM_SymmetricKeyData_Decrypt + (&sensitiveStream, /* output, caller frees */ + &sensitiveStreamSize, /* output */ + tpm_daa_blob.sensitiveData.buffer, /* input */ + tpm_daa_blob.sensitiveData.size, /* input */ + tpm_state->tpm_permanent_data.daaBlobKey); /* dec key */ + } + if (rc == 0) { + stream = sensitiveStream; + stream_size = sensitiveStreamSize; + rc = TPM_DAASensitive_Load(tpm_daa_sensitive, &stream, &stream_size); + } + if (rc == 0) { + if (stream_size != 0) { + printf("TPM_ComputeDecrypt: Error, bad sensitive input size %u\n", sensitiveStreamSize); + rc = TPM_DAA_INPUT_DATA0; + } + } + TPM_DAABlob_Delete(&tpm_daa_blob); /* @1 */ + free(sensitiveStream); /* @2 */ + return rc; +} + +/* TPM_SHA1_BignumGenerate() converts the BIGNUM 'bn' to an array, enlarges the array to 'size', and + computes the SHA-1 hash + +*/ + +TPM_RESULT TPM_SHA1_BignumGenerate(TPM_DIGEST tpm_digest, + TPM_BIGNUM bn, + uint32_t size) +{ + TPM_RESULT rc = 0; + unsigned char *bin = NULL; /* freed @1 */ + unsigned int bytes; + unsigned char *newBin = NULL; /* freed @2, new buffer, enlarged */ + + if (rc == 0) { + rc = TPM_bn2binMalloc(&bin, &bytes, bn, 0); /* freed @1 */ + } + if (rc == 0) { + printf(" TPM_SHA1_BignumGenerate: enlarge to %u bytes, is %u bytes\n", size, bytes); + if (bytes != size) { + /* canonicalize the array size */ + if (rc == 0) { + rc = TPM_ComputeEnlarge(&newBin, size, /* output buffer */ + bin, bytes ); /* inout buffer */ + } + if (rc == 0) { + rc = TPM_SHA1(tpm_digest, + size, newBin, + 0, NULL); + } + } + else { + /* already canonicalized */ + rc = TPM_SHA1(tpm_digest, + bytes, bin, + 0, NULL); + } + } + free(bin); /* @1 */ + free(newBin); /* @2 */ + return rc; +} + +/* TPM_SHA1_SizedBufferCheck() enlarges the TPM_SIZED_BUFFER to 'size', computes the SHA-1 hash, + and validates the digest against 'tpm_digest' + + As a side effect, the TPM_SIZED_BUFFER may be enlarged. +*/ + +TPM_RESULT TPM_SHA1_SizedBufferCheck(TPM_DIGEST tpm_digest, + TPM_SIZED_BUFFER *tpm_sized_buffer, + uint32_t size) +{ + TPM_RESULT rc = 0; + + if (rc == 0) { + printf(" TPM_SHA1_SizedBufferCheck: enlarge to %u bytes, is %u bytes\n", + size, tpm_sized_buffer->size); + if (tpm_sized_buffer->size != size) { + /* canonicalize the array size */ + rc = TPM_SizedBuffer_ComputeEnlarge(tpm_sized_buffer, size); + } + } + if (rc == 0) { + rc = TPM_SHA1_Check(tpm_digest, + tpm_sized_buffer->size, tpm_sized_buffer->buffer, + 0, NULL); + } + return rc; +} + +/* + Processing functions +*/ + +/* 26.1 TPM_DAA_Join rev 99 + + TPM_DAA_Join is the process that establishes the DAA parameters in the TPM for a specific DAA + issuing authority. + + outputSize and outputData are always included in the outParamDigest. This includes stage + 0, where the outputData contains the DAA session handle. +*/ + +TPM_RESULT TPM_Process_DAAJoin(tpm_state_t *tpm_state, + TPM_STORE_BUFFER *response, + TPM_TAG tag, + uint32_t paramSize, /* of remaining parameters*/ + TPM_COMMAND_CODE ordinal, + unsigned char *command, + TPM_TRANSPORT_INTERNAL *transportInternal) +{ + TPM_RESULT rcf = 0; /* fatal error precluding response */ + TPM_RESULT returnCode = TPM_SUCCESS; /* command return code */ + + /* input parameters */ + TPM_HANDLE daaHandle; /* Session handle */ + BYTE stage = 0; /* Processing stage of join */ + TPM_SIZED_BUFFER inputData0; /* Data to be used by this capability */ + TPM_SIZED_BUFFER inputData1; /* Data to be used by this capability */ + TPM_AUTHHANDLE authHandle; /* The authorization session handle used for owner + authentication */ + TPM_NONCE nonceOdd; /* Nonce generated by system associated with authHandle */ + TPM_BOOL continueAuthSession = TRUE; /* Continue use flag, TRUE if handle is still + active */ + TPM_AUTHDATA ownerAuth; /* The authorization session digest for inputs and + owner. HMAC key: ownerAuth. */ + + /* processing */ + unsigned char * inParamStart; /* starting point of inParam's */ + unsigned char * inParamEnd; /* ending point of inParam's */ + TPM_DIGEST inParamDigest; + TPM_BOOL auditStatus; /* audit the ordinal */ + TPM_BOOL transportEncrypt; /* wrapped in encrypted transport session */ + TPM_BOOL authHandleValid = FALSE; + TPM_BOOL daaHandleValid = FALSE; + TPM_AUTH_SESSION_DATA *auth_session_data; /* session data for authHandle */ + TPM_SECRET *hmacKey; + TPM_DAA_SESSION_DATA *tpm_daa_session_data; /* DAA session for handle */ + + /* output parameters */ + uint32_t outParamStart; /* starting point of outParam's */ + uint32_t outParamEnd; /* ending point of outParam's */ + TPM_DIGEST outParamDigest; + TPM_SIZED_BUFFER outputData; /* Data produced by this capability */ + + printf("TPM_Process_DAAJoin: Ordinal Entry\n"); + TPM_SizedBuffer_Init(&inputData0); /* freed @1 */ + TPM_SizedBuffer_Init(&inputData1); /* freed @2 */ + TPM_SizedBuffer_Init(&outputData); /* freed @3 */ + /* + get inputs + */ + /* get handle */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_Load32(&daaHandle, &command, ¶mSize); + } + /* save the starting point of inParam's for authorization and auditing */ + inParamStart = command; + /* get stage */ + if (returnCode == TPM_SUCCESS) { + printf("TPM_Process_DAAJoin: daaHandle %08x\n", daaHandle); + returnCode = TPM_Load8(&stage, &command, ¶mSize); + } + if (returnCode == TPM_SUCCESS) { + printf("TPM_Process_DAAJoin: stage %u\n", stage); + /* For stages after stage 0, daaHandle is an input. Mark it valid so it can be terminated + on error. */ + if (stage > 0) { + daaHandleValid = TRUE; + } + /* get inputData0 */ + returnCode = TPM_SizedBuffer_Load(&inputData0, &command, ¶mSize); + } + /* get inputData1 */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_SizedBuffer_Load(&inputData1, &command, ¶mSize); + } + /* save the ending point of inParam's for authorization and auditing */ + inParamEnd = command; + /* digest the input parameters */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_GetInParamDigest(inParamDigest, /* output */ + &auditStatus, /* output */ + &transportEncrypt, /* output */ + tpm_state, + tag, + ordinal, + inParamStart, + inParamEnd, + transportInternal); + } + /* check state */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_CheckState(tpm_state, tag, TPM_CHECK_ALL); + } + /* check tag */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_CheckRequestTag1(tag); + } + /* get the 'below the line' authorization parameters */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_AuthParams_Get(&authHandle, + &authHandleValid, + nonceOdd, + &continueAuthSession, + ownerAuth, + &command, ¶mSize); + } + if (returnCode == TPM_SUCCESS) { + if (paramSize != 0) { + printf("TPM_Process_DAAJoin: Error, command has %u extra bytes\n", + paramSize); + returnCode = TPM_BAD_PARAM_SIZE; + } + } + /* do not terminate sessions if the command did not parse correctly */ + if (returnCode != TPM_SUCCESS) { + authHandleValid = FALSE; + } + /* + Processing + */ + /* 1. Use ownerAuth to verify that the Owner authorized all TPM_DAA_Join input parameters. */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_AuthSessions_GetData(&auth_session_data, + &hmacKey, + tpm_state, + authHandle, + TPM_PID_NONE, + TPM_ET_OWNER, + ordinal, + NULL, + &(tpm_state->tpm_permanent_data.ownerAuth), /* OIAP */ + tpm_state->tpm_permanent_data.ownerAuth); /* OSAP */ + } + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_Authdata_Check(tpm_state, + *hmacKey, /* owner HMAC key */ + inParamDigest, + auth_session_data, /* authorization session */ + nonceOdd, /* Nonce generated by system + associated with authHandle */ + continueAuthSession, + ownerAuth); /* Authorization digest for input */ + } + /* + Common to most or all stages + */ + /* Validate the DAA session handle after stage 0, stage 0 assigns the handle */ + if (returnCode == TPM_SUCCESS) { + if (stage > 0) { + returnCode = + TPM_DaaSessions_GetEntry(&tpm_daa_session_data, /* returns entry in array */ + tpm_state->tpm_stclear_data.daaSessions, /* array */ + daaHandle); + } + } + /* Verify that the input state is consistent with the current TPM state */ + if (returnCode == TPM_SUCCESS) { + if (stage > 0) { + returnCode = TPM_DaaSessionData_CheckStage(tpm_daa_session_data, stage); + } + } + /* Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific || DAA_joinSession) and + return error TPM_DAA_TPM_SETTINGS on mismatch */ + if (returnCode == TPM_SUCCESS) { + if (stage >= 1) { + returnCode = TPM_DAADigestContext_CheckDigestJoin(tpm_daa_session_data); + } + } + /* Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return error + TPM_DAA_ISSUER_SETTINGS on mismatch */ + if (returnCode == TPM_SUCCESS) { + if (stage >= 3) { + returnCode = + TPM_SHA1_CheckStructure(tpm_daa_session_data->DAA_tpmSpecific.DAA_digestIssuer, + &(tpm_daa_session_data->DAA_issuerSettings), + (TPM_STORE_FUNCTION_T)TPM_DAAIssuer_Store, + TPM_DAA_ISSUER_SETTINGS); + } + } + /* Stages */ + if (returnCode == TPM_SUCCESS) { + switch (stage) { + case 0 : + returnCode = TPM_DAAJoin_Stage00(tpm_state, + &tpm_daa_session_data, /* entry in array */ + &daaHandleValid, + &outputData, &inputData0); + if (daaHandleValid) { + /* For stage 0, daaHandle may be generated. Extract it from the DAA session and + mark it valid, so the session can be terminated on error. */ + daaHandle = tpm_daa_session_data->daaHandle; + } + break; + case 1 : + returnCode = TPM_DAAJoin_Stage01(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 2 : + returnCode = TPM_DAAJoin_Stage02(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 3 : + returnCode = TPM_DAAJoin_Stage03(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0); + break; + case 4 : + returnCode = TPM_DAAJoin_Stage04(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 5 : + returnCode = TPM_DAAJoin_Stage05(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 6 : + returnCode = TPM_DAAJoin_Stage06(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 7 : + returnCode = TPM_DAAJoin_Stage07(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 8 : + returnCode = TPM_DAAJoin_Stage08(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0); + break; + case 9 : + returnCode = TPM_DAAJoin_Stage09_Sign_Stage2(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 10 : + returnCode = TPM_DAAJoin_Stage10_Sign_Stage3(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 11 : + returnCode = TPM_DAAJoin_Stage11_Sign_Stage4(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 12 : + returnCode = TPM_DAAJoin_Stage12(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 13 : + returnCode = TPM_DAAJoin_Stage13_Sign_Stage6(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0, &inputData1); + break; + case 14 : + returnCode = TPM_DAAJoin_Stage14_Sign_Stage7(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0); + break; + case 15 : + returnCode = TPM_DAAJoin_Stage15_Sign_Stage8(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0); + break; + case 16 : + returnCode = TPM_DAAJoin_Stage16_Sign_Stage9(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0); + break; + case 17 : + returnCode = TPM_DAAJoin_Stage17_Sign_Stage11(tpm_state, + tpm_daa_session_data, + &outputData); + break; + case 18 : + returnCode = TPM_DAAJoin_Stage18_Sign_Stage12(tpm_state, + tpm_daa_session_data, + &outputData); + break; + case 19 : + returnCode = TPM_DAAJoin_Stage19(tpm_state, + tpm_daa_session_data, + &outputData); + break; + case 20 : + returnCode = TPM_DAAJoin_Stage20(tpm_state, + tpm_daa_session_data, + &outputData); + break; + case 21 : + returnCode = TPM_DAAJoin_Stage21(tpm_state, + tpm_daa_session_data, + &outputData); + break; + case 22 : + returnCode = TPM_DAAJoin_Stage22(tpm_state, + tpm_daa_session_data, + &outputData, &inputData0); + break; + case 23 : + returnCode = TPM_DAAJoin_Stage23(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + case 24 : + returnCode = TPM_DAAJoin_Stage24(tpm_state, + tpm_daa_session_data, + &outputData); + break; + default : + printf("TPM_Process_DAAJoin: Error, Illegal stage\n"); + returnCode = TPM_DAA_STAGE; + } + } + /* + Common to most or all stages + */ + if (returnCode == TPM_SUCCESS) { + if (stage >= 2) { + tpm_daa_session_data->DAA_session.DAA_stage++; + } + } + /* 24.e.Terminate the DAA session and all resources associated with the DAA join session + handle. */ + if (returnCode == TPM_SUCCESS) { + if (stage == 24) { + printf("TPM_Process_DAAJoin: Stage 24, terminating DAA session %08x\n", + tpm_daa_session_data->daaHandle); + TPM_DaaSessionData_Delete(tpm_daa_session_data); + } + } + /* 2. Any error return results in the TPM invalidating all resources associated with the + join */ + /* NOTE Done after response processing */ + /* + response + */ + /* standard response: tag, (dummy) paramSize, returnCode. Failure is fatal. */ + if (rcf == 0) { + printf("TPM_Process_DAAJoin: Ordinal returnCode %08x %u\n", + returnCode, returnCode); + rcf = TPM_Sbuffer_StoreInitialResponse(response, tag, returnCode); + } + /* success response, append the rest of the parameters. */ + if (rcf == 0) { + if (returnCode == TPM_SUCCESS) { + /* checkpoint the beginning of the outParam's */ + outParamStart = response->buffer_current - response->buffer; + /* return outputData */ + returnCode = TPM_SizedBuffer_Store(response, &outputData); + /* checkpoint the end of the outParam's */ + outParamEnd = response->buffer_current - response->buffer; + } + /* digest the above the line output parameters */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_GetOutParamDigest(outParamDigest, /* output */ + auditStatus, /* input audit status */ + transportEncrypt, + tag, + returnCode, + ordinal, /* command ordinal */ + response->buffer + outParamStart, /* start */ + outParamEnd - outParamStart); /* length */ + } + /* calculate and set the below the line parameters */ + if (returnCode == TPM_SUCCESS) { + /* no outParam's, set authorization response data */ + returnCode = TPM_AuthParams_Set(response, + *hmacKey, /* owner HMAC key */ + auth_session_data, + outParamDigest, + nonceOdd, + continueAuthSession); + } + /* audit if required */ + if ((returnCode == TPM_SUCCESS) && auditStatus) { + returnCode = TPM_ProcessAudit(tpm_state, + transportEncrypt, + inParamDigest, + outParamDigest, + ordinal); + } + /* adjust the initial response */ + rcf = TPM_Sbuffer_StoreFinalResponse(response, returnCode, tpm_state); + } + /* if there was an error, terminate the session. */ + if (((rcf != 0) || + ((returnCode != TPM_SUCCESS) && (returnCode != TPM_DEFEND_LOCK_RUNNING)) || + !continueAuthSession) && + authHandleValid) { + TPM_AuthSessions_TerminateHandle(tpm_state->tpm_stclear_data.authSessions, authHandle); + } + /* on error, terminate the DAA session */ + if (((rcf != 0) || (returnCode != TPM_SUCCESS)) && daaHandleValid) { + TPM_DaaSessions_TerminateHandle(tpm_state->tpm_stclear_data.daaSessions, + daaHandle); + } + /* + cleanup + */ + TPM_SizedBuffer_Delete(&inputData0); /* @1 */ + TPM_SizedBuffer_Delete(&inputData1); /* @2 */ + TPM_SizedBuffer_Delete(&outputData); /* @3 */ + return rcf; +} + +/* 26.2 TPM_DAA_Sign rev 99 + + TPM protected capability; user must provide authorizations from the TPM Owner. + + outputSize and outputData are always included in the outParamDigest. This includes stage + 0, where the outputData contains the DAA session handle. +*/ + +TPM_RESULT TPM_Process_DAASign(tpm_state_t *tpm_state, + TPM_STORE_BUFFER *response, + TPM_TAG tag, + uint32_t paramSize, /* of remaining parameters*/ + TPM_COMMAND_CODE ordinal, + unsigned char *command, + TPM_TRANSPORT_INTERNAL *transportInternal) +{ + TPM_RESULT rcf = 0; /* fatal error precluding response */ + TPM_RESULT returnCode = TPM_SUCCESS; /* command return code */ + + /* input parameters */ + TPM_HANDLE daaHandle; /* Handle to the sign session */ + BYTE stage = 0; /* Stage of the sign process */ + TPM_SIZED_BUFFER inputData0; /* Data to be used by this capability */ + TPM_SIZED_BUFFER inputData1; /* Data to be used by this capability */ + TPM_AUTHHANDLE authHandle; /* The authorization session handle used for owner + authentication */ + TPM_NONCE nonceOdd; /* Nonce generated by system associated with authHandle */ + TPM_BOOL continueAuthSession = TRUE; /* Continue use flag, TRUE if handle is still + active */ + TPM_AUTHDATA ownerAuth; /* The authorization session digest for inputs and + owner. HMAC key: ownerAuth. */ + + /* processing */ + unsigned char * inParamStart; /* starting point of inParam's */ + unsigned char * inParamEnd; /* ending point of inParam's */ + TPM_DIGEST inParamDigest; + TPM_BOOL auditStatus; /* audit the ordinal */ + TPM_BOOL transportEncrypt; /* wrapped in encrypted transport session */ + TPM_BOOL authHandleValid = FALSE; + TPM_BOOL daaHandleValid = FALSE; + TPM_AUTH_SESSION_DATA *auth_session_data; /* session data for authHandle */ + TPM_SECRET *hmacKey; + TPM_DAA_SESSION_DATA *tpm_daa_session_data; /* DAA session for handle */ + + /* output parameters */ + uint32_t outParamStart; /* starting point of outParam's */ + uint32_t outParamEnd; /* ending point of outParam's */ + TPM_DIGEST outParamDigest; + TPM_SIZED_BUFFER outputData; /* Data produced by this capability */ + + printf("TPM_Process_DAASign: Ordinal Entry\n"); + TPM_SizedBuffer_Init(&inputData0); /* freed @1 */ + TPM_SizedBuffer_Init(&inputData1); /* freed @2 */ + TPM_SizedBuffer_Init(&outputData); /* freed @3 */ + /* + get inputs + */ + /* get handle */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_Load32(&daaHandle, &command, ¶mSize); + } + /* save the starting point of inParam's for authorization and auditing */ + inParamStart = command; + /* get stage */ + if (returnCode == TPM_SUCCESS) { + printf("TPM_Process_DAASign: daaHandle %08x\n", daaHandle); + returnCode = TPM_Load8(&stage, &command, ¶mSize); + } + if (returnCode == TPM_SUCCESS) { + printf("TPM_Process_DAASign: stage %u\n", stage); + /* For stages after stage 0, daaHandle is an input. Mark it valid so it can be terminated + on error. */ + if (stage > 0) { + daaHandleValid = TRUE; + } + /* get inputData0 */ + returnCode = TPM_SizedBuffer_Load(&inputData0, &command, ¶mSize); + } + /* get inputData1 */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_SizedBuffer_Load(&inputData1, &command, ¶mSize); + } + /* save the ending point of inParam's for authorization and auditing */ + inParamEnd = command; + /* digest the input parameters */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_GetInParamDigest(inParamDigest, /* output */ + &auditStatus, /* output */ + &transportEncrypt, /* output */ + tpm_state, + tag, + ordinal, + inParamStart, + inParamEnd, + transportInternal); + } + /* check state */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_CheckState(tpm_state, tag, TPM_CHECK_ALL); + } + /* check tag */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_CheckRequestTag1(tag); + } + /* get the 'below the line' authorization parameters */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_AuthParams_Get(&authHandle, + &authHandleValid, + nonceOdd, + &continueAuthSession, + ownerAuth, + &command, ¶mSize); + } + if (returnCode == TPM_SUCCESS) { + if (paramSize != 0) { + printf("TPM_Process_DAASign: Error, command has %u extra bytes\n", + paramSize); + returnCode = TPM_BAD_PARAM_SIZE; + } + } + /* do not terminate sessions if the command did not parse correctly */ + if (returnCode != TPM_SUCCESS) { + authHandleValid = FALSE; + } + /* + Processing + */ + /* 1. Use ownerAuth to verify that the Owner authorized all TPM_DAA_Sign input parameters. */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_AuthSessions_GetData(&auth_session_data, + &hmacKey, + tpm_state, + authHandle, + TPM_PID_NONE, + TPM_ET_OWNER, + ordinal, + NULL, + &(tpm_state->tpm_permanent_data.ownerAuth), /* OIAP */ + tpm_state->tpm_permanent_data.ownerAuth); /* OSAP */ + } + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_Authdata_Check(tpm_state, + *hmacKey, /* owner HMAC key */ + inParamDigest, + auth_session_data, /* authorization session */ + nonceOdd, /* Nonce generated by system + associated with authHandle */ + continueAuthSession, + ownerAuth); /* Authorization digest for input */ + } + /* + Common to most or all stages + */ + /* Validate the DAA session handle after stage 0, stage 0 assigns the handle */ + if (returnCode == TPM_SUCCESS) { + if (stage > 0) { + returnCode = + TPM_DaaSessions_GetEntry(&tpm_daa_session_data, /* returns entry in array */ + tpm_state->tpm_stclear_data.daaSessions, /* array */ + daaHandle); + } + } + /* Verify that the input state is consistent with the current TPM state */ + if (returnCode == TPM_SUCCESS) { + if (stage > 0) { + returnCode = TPM_DaaSessionData_CheckStage(tpm_daa_session_data, stage); + } + } + /* Verify that DAA_session -> DAA_digestContext == SHA-1(DAA_tpmSpecific) and return error + TPM_DAA_TPM_SETTINGS on mismatch */ + if (returnCode == TPM_SUCCESS) { + if (stage >= 2) { + returnCode = + TPM_SHA1_CheckStructure(tpm_daa_session_data->DAA_session.DAA_digestContext, + &(tpm_daa_session_data->DAA_tpmSpecific), + (TPM_STORE_FUNCTION_T)TPM_DAATpm_Store, + TPM_DAA_TPM_SETTINGS); + } + } + /* Verify that DAA_tpmSpecific -> DAA_digestIssuer == SHA-1(DAA_issuerSettings) and return error + TPM_DAA_ISSUER_SETTINGS on mismatch */ + if (returnCode == TPM_SUCCESS) { + if (stage >= 2) { + returnCode = + TPM_SHA1_CheckStructure(tpm_daa_session_data->DAA_tpmSpecific.DAA_digestIssuer, + &(tpm_daa_session_data->DAA_issuerSettings), + (TPM_STORE_FUNCTION_T)TPM_DAAIssuer_Store, + TPM_DAA_ISSUER_SETTINGS); + } + } + /* Stages */ + if (returnCode == TPM_SUCCESS) { + switch (stage) { + case 0 : + returnCode = TPM_DAASign_Stage00(tpm_state, + &tpm_daa_session_data, /* returns entry in array */ + &daaHandleValid, + &outputData, + &inputData0); + if (daaHandleValid) { + /* For stage 0, daaHandle may be generated. Extract it from the DAA session and + mark it valid, so the session can be terminated on error. */ + daaHandle = tpm_daa_session_data->daaHandle; + } + break; + case 1 : + returnCode = TPM_DAASign_Stage01(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + case 2 : + returnCode = TPM_DAAJoin_Stage09_Sign_Stage2(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0, &inputData1); + break; + case 3 : + returnCode = TPM_DAAJoin_Stage10_Sign_Stage3(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0, &inputData1); + break; + case 4 : + returnCode = TPM_DAAJoin_Stage11_Sign_Stage4(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0, &inputData1); + break; + case 5 : + returnCode = TPM_DAASign_Stage05(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0, &inputData1); + break; + case 6 : + returnCode = TPM_DAAJoin_Stage13_Sign_Stage6(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0, &inputData1); + break; + case 7 : + returnCode = TPM_DAAJoin_Stage14_Sign_Stage7(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + case 8 : + returnCode = TPM_DAAJoin_Stage15_Sign_Stage8(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + case 9 : + returnCode = TPM_DAAJoin_Stage16_Sign_Stage9(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + case 10 : + returnCode = TPM_DAASign_Stage10(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0, &inputData1); + break; + case 11 : + returnCode = TPM_DAAJoin_Stage17_Sign_Stage11(tpm_state, + tpm_daa_session_data, + &outputData); + break; + case 12 : + returnCode = TPM_DAAJoin_Stage18_Sign_Stage12(tpm_state, + tpm_daa_session_data, + &outputData); + break; + case 13 : + returnCode = TPM_DAASign_Stage13(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + case 14 : + returnCode = TPM_DAASign_Stage14(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + case 15 : + returnCode = TPM_DAASign_Stage15(tpm_state, + tpm_daa_session_data, + &outputData, + &inputData0); + break; + default : + printf("TPM_Process_DAASign: Error, Illegal stage\n"); + returnCode = TPM_DAA_STAGE; + } + } + /* + Common to most or all stages + */ + if (returnCode == TPM_SUCCESS) { + tpm_daa_session_data->DAA_session.DAA_stage++; + } + /* 15.j. Terminate the DAA session and all resources associated with the DAA sign session + handle. */ + if (returnCode == TPM_SUCCESS) { + if (stage == 15) { + printf("TPM_Process_DAASign: Stage 15, terminating DAA session %08x\n", + tpm_daa_session_data->daaHandle); + TPM_DaaSessionData_Delete(tpm_daa_session_data); + } + } + /* 2. Any error return results in the TPM invalidating all resources associated with the + join */ + /* NOTE Done after response processing */ + /* + response + */ + /* standard response: tag, (dummy) paramSize, returnCode. Failure is fatal. */ + if (rcf == 0) { + printf("TPM_Process_DAASign: Ordinal returnCode %08x %u\n", + returnCode, returnCode); + rcf = TPM_Sbuffer_StoreInitialResponse(response, tag, returnCode); + } + /* success response, append the rest of the parameters. */ + if (rcf == 0) { + if (returnCode == TPM_SUCCESS) { + /* checkpoint the beginning of the outParam's */ + outParamStart = response->buffer_current - response->buffer; + /* return outputData */ + returnCode = TPM_SizedBuffer_Store(response, &outputData); + /* checkpoint the end of the outParam's */ + outParamEnd = response->buffer_current - response->buffer; + } + /* digest the above the line output parameters */ + if (returnCode == TPM_SUCCESS) { + returnCode = TPM_GetOutParamDigest(outParamDigest, /* output */ + auditStatus, /* input audit status */ + transportEncrypt, + tag, + returnCode, + ordinal, /* command ordinal */ + response->buffer + outParamStart, /* start */ + outParamEnd - outParamStart); /* length */ + } + /* calculate and set the below the line parameters */ + if (returnCode == TPM_SUCCESS) { + /* no outParam's, set authorization response data */ + returnCode = TPM_AuthParams_Set(response, + *hmacKey, /* owner HMAC key */ + auth_session_data, + outParamDigest, + nonceOdd, + continueAuthSession); + } + /* audit if required */ + if ((returnCode == TPM_SUCCESS) && auditStatus) { + returnCode = TPM_ProcessAudit(tpm_state, + transportEncrypt, + inParamDigest, + outParamDigest, + ordinal); + } + /* adjust the initial response */ + rcf = TPM_Sbuffer_StoreFinalResponse(response, returnCode, tpm_state); + } + /* if there was an error, terminate the session. */ + if (((rcf != 0) || + ((returnCode != TPM_SUCCESS) && (returnCode != TPM_DEFEND_LOCK_RUNNING)) || + !continueAuthSession) && + authHandleValid) { + TPM_AuthSessions_TerminateHandle(tpm_state->tpm_stclear_data.authSessions, authHandle); + } + /* on error, terminate the DAA session */ + if (((rcf != 0) || (returnCode != TPM_SUCCESS)) && daaHandleValid) { + TPM_DaaSessions_TerminateHandle(tpm_state->tpm_stclear_data.daaSessions, + daaHandle); + } + /* + cleanup + */ + TPM_SizedBuffer_Delete(&inputData0); /* @1 */ + TPM_SizedBuffer_Delete(&inputData1); /* @2 */ + TPM_SizedBuffer_Delete(&outputData); /* @3 */ + return rcf; +} -- cgit v1.2.3