/********************************************************************************/ /* */ /* 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; }