📄 sps.c
字号:
/** * \file * Secure Patch System Code * * \version $Revision$ $State$ * * \date $Date$ * * \author <a href="mailto:Axel.Wachtler@amd.com">Axel Wachtler</a> * * \par Last changed by: * $Author$ * *****************************************************************************//* * Copyright 2002 ADVANCED MICRO DEVICES, INC. All Rights Reserved. * * This software and any related documentation (the "Materials") are the * confidential proprietary information of AMD. Unless otherwise provided * in an agreement specifically licensing the Materials, the Materials are * provided in confidence and may not to be used, distributed, modified, or * reproduced in whole or in part by any means. * * LIMITATION OF LIABILITY: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY * EXPRESS OR IMPLIED WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO * WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY * PARTICULAR PURPOSE, OR WARRANTIES ARISING FORM CONDUCT, COURSE OF * DEALING, OR USAGE OF TRADE. IN NO EVENT SHALL AMD OR ITS LICENSORS BE * LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, * DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF * INFORMATION) ARISING OUT OF THE USE OF OR INABILITY TO USE THE * MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR * LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE * ABOVE LIMITATION MAY NOT APPLY TO YOU. * * AMD does not assume any responsibility for any errors which may appear * in the Materials nor any responsibility to support or update the * Materials. AMD retains the right to modify the Materials at any time, * without notice, and is not obligated to provide such modified Materials * to you. * * NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make * any further information, software, technical information, know-how, or * show-how available to you. * *//****************************************************************************** Includes*****************************************************************************/#include "sec.h"#include "ssfif.h"#include "sps.h"#include "dve_api.h"#include "sps_hc.h"/****************************************************************************** Data*****************************************************************************//****************************************************************************** Static Function Declarations*****************************************************************************//** \defgroup SpsFunctions SPS Functions*//**\{*//** * \brief * Initialize the SPS context. * * The context data are hold in a global structure. * This function have to be called before the first * * * \param i is an int * \return SIS_SUCCESS or SIS_FAILURE */SpsSuccess_t SpsInitCtx(SpsContext_t * pCtx){ SpsSuccess_t ret; ret = SPS_UNSUCCESSFUL; do { if (pCtx == NULL) { ret = SPS_NULL_PTR_FAIL; break; } if (pCtx->Magic == SPS_MAGIC) { ret = SPS_INIT_FAIL; break; } ssf_memset(pCtx, 0, sizeof(SpsContext_t)); pCtx->Magic = SPS_MAGIC; pCtx->OverFlowObserved = FALSE; /* be sure, cause we do not know, if false is 0 */ ret = SPS_SUCCESSFUL; } while (0); /* show memory diagnostics if apropriate bit is 0 */ if ((SsfGetSecurityEnableMask() & SECURITY_ENABLE_PRNMEMSTAT) == 0) { SsfUtilMemoryPrintPoolInfo(); } return ret;}/** * @brief process the info field of a patch package and store * information in the sps context structure * * @param pCtx pointer to sps context structure * @param pInfo pointer to patch package info structure * * @return */SpsSuccess_t SpsProcessInfo(SpsContext_t * pCtx, SpsPpPatchInfo_t * pInfo, Int32 Size){ SpsSuccess_t ret; ret = SPS_UNSUCCESSFUL; DP0(("==> SpsProcessInfo: SecMask=0x%08x SecDisabled=%d", SsfGetSecurityEnableMask(), SsfIsSecurityDisabled())); do { if ((pCtx == NULL) || (pInfo == NULL) || (Size < PP_INFO_LENGTH)) { ret = SPS_NULL_PTR_FAIL; break; } /* reset all variables, which depend on a patch package */ SpsResetContext(pCtx); ret = SpsEvaluatePatchInfo(pInfo); if (ret != SPS_SUCCESSFUL) { break; } ret = SpsSecurityInit(pCtx, pInfo); } while (0); /* show memory diagnostics */ if ((SsfGetSecurityEnableMask() & SECURITY_ENABLE_PRNMEMSTAT) == 0) { SsfUtilMemoryPrintPoolInfo(); } return ret;}/** * @brief process the header field of a patch package and store * information in the sps context structure * (with each call of this function, the offset * for the patch buffer is reseted to 0) * * @param pCtx pointer to sps context structure * @param pData pointer to patch package header structure * * @retval pNbPatchRecords number of patch records, that stored * in the patch package * @retval pPatchSize netto size of the patch package, e.g. if * if 2 records with lenths and 4 and 22, * the return value is: * 2 * sizeof(Addr) 8 * + 2 * sizeof(Length) 8 * + 4 * sizeof(int8) 4 (rec 1) * + 32 * sizeof(int8) 22 (rec 2) * pPatchSize = 42 * * @return */SpsSuccess_t SpsProcessHeader(SpsContext_t * pCtx, Int8 * pData, Int32 Size, Int32 * pPatchSize){ SpsSuccess_t ret; Int32 PrFragNb; Int32 rsize;#if HSS_SAVE_ALIGMENT SpsPpPatchHeader_t Hdr;#endif SpsPpPatchHeader_t *pHdr; DP0(("==> SpsProcessHeader")); pHdr = NULL; ret = SPS_UNSUCCESSFUL; do { if ((pCtx == NULL) || (pData == NULL) || (Size != PP_HEADER_LENGTH) || (pPatchSize == NULL)) { ret = SPS_NULL_PTR_FAIL; break; }#if HSS_SAVE_ALIGMENT hss_memcpy(&Hdr, pData, PP_HEADER_LENGTH); pHdr = &Hdr;#else pHdr = (SpsPpPatchHeader_t *) pData;#endif rsize = SpsSecurityUpdate(pCtx, (Int8 *) pHdr, Size); if (rsize != Size) { DP0(("ERROR: invalid patch header")); break; } ret = SpsEvaluatePatchHeader(pHdr); if (ret != SPS_SUCCESSFUL) { break; } ssf_memcpy(&(pCtx->patchheader), pHdr, PP_HEADER_LENGTH); pCtx->PatchBufferOffset = 0; PrFragNb = pCtx->patchheader.PrSize / PP_FRAGMENTATION_SIZE; if ((pCtx->patchheader.PrSize % PP_FRAGMENTATION_SIZE) != 0) { PrFragNb++; } /* former alignment code for Bug 2105 *pPatchSize = pCtx->patchheader.PrSize + sizeof(Int32); */ *pPatchSize = pCtx->patchheader.PrSize; ret = SpsAssignPatchBufferToContext(pCtx); } while (0); /* show memory diagnostics if apropriate bit is 0 */ if ((SsfGetSecurityEnableMask() & SECURITY_ENABLE_PRNMEMSTAT) == 0) { SsfUtilMemoryPrintPoolInfo(); } return ret;}/** * @brief * process the patch fragment and copy the patch data to the assigned buffer. * * * @param pCtx SPS context structure * @param pEpr pointer to a encapsulated patch record * * @return * SPS_SUCCESSFUL if operation was ok * SPS_NULL_PTR_FAIL if one of the input pointers is NULL * SPS_NO_BUFFER_FAIL if there was no buffer assigned with SpsAssignMemory() * SPS_SMALL_BUFFER_FAIL if the buffer is smaller then the expected * patch size * */SpsSuccess_t SpsProcessPrFragment(SpsContext_t * pCtx, Int8 * pData, Int32 Size){ SpsSuccess_t ret; DP0(("==> SpsProcessPrFragment")); ret = SPS_UNSUCCESSFUL; do { if ((pCtx == NULL) || (pData == NULL) || (Size == 0)) { ret = SPS_NULL_PTR_FAIL; break; } /* update security values */ SpsSecurityUpdate(pCtx, (Int8 *) pData, Size); /* copy values to buffer, if possible */ if (pCtx->pPatchBuffer == NULL) { ret = SPS_NO_BUFFER_FAIL; break; } if ((pCtx->PatchBufferOffset + Size) > pCtx->PatchBufferSize) { pCtx->OverFlowObserved = TRUE; ret = SPS_SMALL_BUFFER_FAIL; break; } ssf_memcpy(&pCtx->pPatchBuffer[pCtx->PatchBufferOffset], pData, Size); pCtx->PatchBufferOffset += Size; /* fix for Bug 2093 */ pCtx->PatchRecordCnt++; ret = SPS_SUCCESSFUL; } while (0); /* show memory diagnostics if apropriate bit is 0 */ if ((SsfGetSecurityEnableMask() & SECURITY_ENABLE_PRNMEMSTAT) == 0) { SsfUtilMemoryPrintPoolInfo(); } return ret;}/** * @brief finish the processing of a patch package * * @param pCtx sps context pointer * @retval pNbPatchRecords number of patch records, which are received * @retval pTrustLevel trust level of the patch (5 is highest) * @retval pVersionInfo 8 byte array of the patch version (2 * Int32) * @retval ppPatchData address of the shadow buffer with the patch data * * @return SPS_SUCCESSFUL or errorcode in case of * any suspectness of the received patch * */SpsSuccess_t SpsFinalizePp(SpsContext_t * pCtx, Int8 * pTrustLevel, char *pVersionInfo, Int8 ** ppPatchData){ SpsSuccess_t ret; ret = SPS_UNSUCCESSFUL; DP0(("==> SpsFinalizePp")); do { /* at first check for all fatal errors, which invalidate the patch completely */ if ((pCtx == NULL) || (pTrustLevel == NULL) || (pVersionInfo == NULL) || (ppPatchData == NULL)) { DP0((" SPS_NULL_PTR_FAIL\n")); ret = SPS_NULL_PTR_FAIL; break; } if (pCtx->pPatchBuffer == NULL) { DP0(("ERROR: SPS_NO_BUFFER_FAIL\n")); ret = SPS_NO_BUFFER_FAIL; break; } if (pCtx->OverFlowObserved != FALSE) { DP0(("ERROR: SPS_SMALL_BUFFER_FAIL\n")); ret = SPS_SMALL_BUFFER_FAIL; break; } ret = SpsEvaluatePatchBuffer(pCtx->pPatchBuffer, pCtx->PatchBufferOffset, pCtx->patchheader.PrSize); if (ret != SPS_SUCCESSFUL) { DP0(("ERROR: unconsistent package ret=%d\n", ret)); break; } /* init the return parameters */ *pTrustLevel = SpsComputeTrustLevel(pCtx); ssf_memcpy(pVersionInfo, &(pCtx->patchheader.VersionInfo[0]), PP_VERSION_LENGTH); *ppPatchData = pCtx->pPatchBuffer; /* reinitialize the hash chain for the next package */ if ((SsfGetSecurityEnableMask() & SECURITY_ENABLE_HCRESET) != 0) { if (*pTrustLevel >= 5) { /* we can trust this hash value, it is from a good package */ SpsHashChainReset((SpsHashChainWorkspace_t *) pCtx-> pHashChainWorkspace, &pCtx->patchheader.sha1[0]); } else { /* forget the hash value in this package, it is probably poison */ SpsHashChainReset((SpsHashChainWorkspace_t *) pCtx-> pHashChainWorkspace, NULL); } } pCtx->PatchPkgCounter++; DP0(("pakage %d processed [size=%d, truslevel=%d]", pCtx->PatchPkgCounter, pCtx->patchheader.PrSize, *pTrustLevel)); ret = SPS_SUCCESSFUL; } while (0); SpsResetContext(pCtx); /* show memory diagnostics if apropriate bit is 0 */ if ((SsfGetSecurityEnableMask() & SECURITY_ENABLE_PRNMEMSTAT) == 0) { SsfUtilMemoryPrintPoolInfo(); } return ret;}/* ------------------------------------------------------------------------- *//** \defgroup SpsInternalFunctions SPS Internal Functions*//**\{*//** * @brief evaluate patch info structure * * @param pInfo pointer to structure * * @return SPS_SUCCESSFUL in case of success * SPS_NULL_PTR_FAIL in case of null pointer * SPS_PINFO_FAIL if magic number is wrong */SpsSuccess_t SpsEvaluatePatchInfo(SpsPpPatchInfo_t * pInfo){ SpsSuccess_t ret; ret = SPS_UNSUCCESSFUL; do { if (pInfo == NULL) { ret = SPS_NULL_PTR_FAIL; break; } if (pInfo->MagicNb != PP_MAGIC_NUMBER) { ret = SPS_PINFO_FAIL; break; } ret = SPS_SUCCESSFUL; } while (0); return ret;}/** * @brief evaluate patch header structure * * @param pHeader pointer to structure *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -