blob: 1cbfbcb81aa6b88b04cfe3f12381f41c99fe509b [file] [log] [blame]
/*
Copyright © Trustonic Limited 2013
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. 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.
3. Neither the name of the Trustonic Limited 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 <string.h>
#include "logging.h"
#include "pacmp3.h"
#include "registry.h"
#include "pacmtl.h"
#define ILLEGAL_ELEMENT 0
#define FIRST_ELEMENT 1
#define FIRST_ELEMENT_OFFSET 0
void setCmdElementInfo(uint32_t* elementNbrP, uint8_t* wsmP, uint32_t* elementOffsetP, uint32_t elementLength)
{
if(NULL==elementNbrP || NULL == elementOffsetP || NULL == wsmP)
{
LOGE("pacmtl setCmdElementInfo NULL's in input, not setting the element %ld %ld", (long int) elementNbrP, (long int) elementOffsetP);
return;
}
if(ILLEGAL_ELEMENT==*elementNbrP || (*elementNbrP==FIRST_ELEMENT && *elementOffsetP != FIRST_ELEMENT_OFFSET))
{
LOGE("pacmtl setCmdElementInfo error in input, not setting the element %d %d", *elementNbrP, *elementOffsetP);
return;
}
cmpMapOffsetInfo_t* elementP=(&((cmpCommandHeaderTci_t*)wsmP)->cmpCmdMapOffsetInfo);
elementP+=((*elementNbrP)-1);
elementP->offset=*elementOffsetP;
elementP->len=elementLength;
(*elementNbrP)++; // returning number of next element
(*elementOffsetP)+=elementLength; // returning offset to next element
}
void setCmdMapInfo(uint8_t* wsmP, const mcBulkMap_t* mapInfoP)
{
// mapInfo and *mapinfoP are of different type, thats why assignment instead of memcpy.
((cmpCommandHeaderTci_t*)wsmP)->mapInfo.addr=mapInfoP->sVirtualAddr;
((cmpCommandHeaderTci_t*)wsmP)->mapInfo.len=mapInfoP->sVirtualLen;
}
void setCmdCmpVersionAndCmdId(uint8_t* wsmP, cmpCommandId_t commandId)
{
((cmpCommandHeaderTci_t*)wsmP)->version=CMP_VERSION;
((cmpCommandHeaderTci_t*)wsmP)->commandId=commandId;
}
bool getRspElementInfo(uint32_t* elementNbrP, CMTHANDLE handle, uint32_t* elementOffsetP, uint32_t* elementLengthP)
{
uint8_t* wsmP=NULL;
cmpMapOffsetInfo_t* elementP=NULL;
if(NULL==handle)
{
LOGE("pacmtl setCmdElementInfo ho handle");
*elementLengthP=0;
return false;
}
wsmP=handle->wsmP;
LOGD(">>pacmtl getRspElementInfo %x %x %d %d %d %d", ((cmpResponseHeaderTci_t*)wsmP)->version,
((cmpResponseHeaderTci_t*)wsmP)->responseId,
((cmpResponseHeaderTci_t*)wsmP)->len,
*((uint32_t*)(wsmP+12)),
*((uint32_t*)(wsmP+16)),
*((uint32_t*)(wsmP+20)));
if(NULL==elementNbrP || NULL == elementOffsetP || NULL == elementLengthP || NULL == handle->wsmP)
{
LOGE("pacmtl getRspElementInfo NULL's in input, not setting the element %ld %ld", (long int) elementNbrP, (long int) elementOffsetP);
return false;
}
if(ILLEGAL_ELEMENT==*elementNbrP)
{
LOGE("pacmtl getRspElementInfo error in input (illegal element), not getting the element %d", *elementNbrP);
*elementLengthP=0;
return false;
}
elementP=(cmpMapOffsetInfo_t*)(wsmP+sizeof(cmpResponseHeaderTci_t));
elementP+=((*elementNbrP)-1);
if(elementP->offset+elementP->len > handle->mappedSize)
{
LOGE("pacmtl getRspElementInfo error in input (offset+len too big), not getting the element %d", *elementNbrP);
*elementLengthP=0;
return false;
}
*elementOffsetP=elementP->offset;
*elementLengthP=elementP->len;
LOGD("<<pacmtl getRspElementInfo element %d offset %d length %d", *elementNbrP, *elementOffsetP, *elementLengthP);
(*elementNbrP)++; // returning number of next element
return true;
}
uint32_t getRspCmpVersion(const uint8_t* wsmP)
{
return ((cmpResponseHeaderTci_t*)wsmP)->version;
}
uint32_t getRspCmpId(const uint8_t* wsmP)
{
return ((cmpResponseHeaderTci_t*)wsmP)->responseId;
}
bool isValidResponse(const uint8_t* wsmP)
{
if(NULL==wsmP)
{
LOGE("pacmtl isValidResponse returning false due to NULL wsmP");
return false;
}
if(getRspCmpVersion(wsmP) != CMP_VERSION )
{
LOGE("pacmtl isValidResponse returning false due to cmpVersion 0x%x", getRspCmpVersion(wsmP));
return false;
}
if(IS_RSP(getRspCmpId(wsmP)))
{
return true;
}
LOGE("pacmtl isValidResponse returning false IS_RSP %d", getRspCmpId(wsmP));
return false;
}
bool isValidResponseTo(cmpCommandId_t commandId, const uint8_t* wsmP)
{
LOGD(">>pacmtl isValidResponseTo %d", commandId);
if(isValidResponse(wsmP))
{
if(getRspCmpId(wsmP)==RSP_ID(commandId))
{
LOGD("<<pacmtl isValidResponseTo returning true");
return true;
}
}
LOGE("<<pacmtl isValidResponseTo returning false");
return false;
}
uint32_t getNeededBytesFromResponse(const uint8_t* wsmP)
{
if(!isValidResponse(wsmP))
{
return -1;
}
return ((cmpResponseHeaderTci_t*)wsmP)->len;
}
typedef struct {
uint32_t cmdId;
uint32_t cmdRspSize;
uint32_t cmdContainerSize;
uint32_t rspContainerSize;
} cmpSizes_t;
//
// note that the container sizes are
//
static const cmpSizes_t sizeTable_[] = {
{
MC_CMP_CMD_AUTHENTICATE,
sizeof(cmpMapAuthenticate_t),
0,
0
},
{
MC_CMP_CMD_BEGIN_ROOT_AUTHENTICATION,
sizeof(cmpMapBeginRootAuthentication_t),
SIZEOFROOTCONTAINER,
0
},
{
MC_CMP_CMD_BEGIN_SOC_AUTHENTICATION,
sizeof(cmpMapBeginSocAuthentication_t),
SIZEOFAUTHTOKENCONTAINER,
0
},
{
MC_CMP_CMD_BEGIN_SP_AUTHENTICATION,
sizeof(cmpMapBeginSpAuthentication_t),
SIZEOFROOTCONTAINER+SIZEOFSPCONTAINER,
0
},
{
MC_CMP_CMD_GENERATE_AUTH_TOKEN,
sizeof(cmpMapGenAuthToken_t),
0,
0 //SIZEOFAUTHTOKENCONTAINER
},
{
MC_CMP_CMD_GET_VERSION,
sizeof(cmpMapGetVersion_t),
0,
0
},
{
MC_CMP_CMD_ROOT_CONT_LOCK_BY_ROOT,
sizeof(cmpMapRootContLockByRoot_t),
0,
SIZEOFROOTCONTAINER
},
{
MC_CMP_CMD_ROOT_CONT_REGISTER_ACTIVATE,
sizeof(cmpMapRootContRegisterActivate_t),
0,
SIZEOFROOTCONTAINER
},
{
MC_CMP_CMD_ROOT_CONT_UNLOCK_BY_ROOT,
sizeof(cmpMapRootContUnlockByRoot_t),
0,
SIZEOFROOTCONTAINER
},
{
MC_CMP_CMD_ROOT_CONT_UNREGISTER,
sizeof(cmpMapRootContUnregister_t),
0,
0
},
{
MC_CMP_CMD_SP_CONT_ACTIVATE,
sizeof(cmpMapSpContActivate_t),
0,
SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_SP_CONT_LOCK_BY_ROOT,
sizeof(cmpMapSpContLockByRoot_t),
SIZEOFSPCONTAINER,
SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_SP_CONT_LOCK_BY_SP,
sizeof(cmpMapSpContLockBySp_t),
0,
SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_SP_CONT_REGISTER,
sizeof(cmpMapSpContRegister_t),
0,
SIZEOFROOTCONTAINER+SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_SP_CONT_REGISTER_ACTIVATE,
sizeof(cmpMapSpContRegisterActivate_t),
0,
SIZEOFROOTCONTAINER+SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_SP_CONT_UNLOCK_BY_ROOT,
sizeof(cmpMapSpContUnlockByRoot_t),
SIZEOFSPCONTAINER,
SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_SP_CONT_UNLOCK_BY_SP,
sizeof(cmpMapSpContUnlockBySp_t),
0,
SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_SP_CONT_UNREGISTER,
sizeof(cmpMapSpContUnregister_t),
0,
SIZEOFROOTCONTAINER
},
{
MC_CMP_CMD_TLT_CONT_ACTIVATE,
sizeof(cmpMapTltContActivate_t),
SIZEOFTLTCONTAINER,
SIZEOFTLTCONTAINER
},
{
MC_CMP_CMD_TLT_CONT_LOCK_BY_SP,
sizeof(cmpMapTltContLockBySp_t),
SIZEOFTLTCONTAINER,
SIZEOFTLTCONTAINER
},
{
MC_CMP_CMD_TLT_CONT_PERSONALIZE,
sizeof(cmpMapTltContPersonalize_t),
SIZEOFTLTCONTAINER,
0
},
{
MC_CMP_CMD_TLT_CONT_REGISTER,
sizeof(cmpMapTltContRegister_t),
0,
SIZEOFSPCONTAINER+SIZEOFTLTCONTAINER
},
{
MC_CMP_CMD_TLT_CONT_REGISTER_ACTIVATE,
sizeof(cmpMapTltContRegisterActivate_t),
0,
SIZEOFSPCONTAINER+SIZEOFTLTCONTAINER
},
{
MC_CMP_CMD_TLT_CONT_UNLOCK_BY_SP,
sizeof(cmpMapTltContUnlockBySp_t),
SIZEOFTLTCONTAINER,
SIZEOFTLTCONTAINER
},
{
MC_CMP_CMD_TLT_CONT_UNREGISTER,
sizeof(cmpMapTltContUnregister_t),
0,
SIZEOFSPCONTAINER
},
{
MC_CMP_CMD_GET_SUID,
sizeof(cmpMapGetSuid_t),
0,
0
},
{
MC_CMP_CMD_AUTHENTICATE_TERMINATE,
sizeof(cmpMapAuthenticateTerminate_t),
0,
0
}
};
const cmpSizes_t* getCmpSizeInfo(uint32_t cmdId)
{
int i = 0;
for ( i = 0; i < sizeof(sizeTable_)/sizeof(cmpSizes_t); i++)
{
if (cmdId == sizeTable_[i].cmdId)
{
return &sizeTable_[i];
}
}
LOGE("getCmpSizeInfo command %d not supported", cmdId);
return NULL;
}
uint32_t bigger(uint32_t first, uint32_t second)
{
return (first>second?first:second);
}
uint32_t getTotalMappedBufferSize(CmpMessage* commandP)
{
const cmpSizes_t* sizesP=getCmpSizeInfo(getCmpCommandId(commandP->contentP));
if(NULL==sizesP) return 0;
uint32_t commandSize=bigger(sizesP->cmdRspSize, commandP->length);
uint32_t containerSize=bigger(sizesP->cmdContainerSize, sizesP->rspContainerSize);
LOGD("pacmtl getTotalMappedBufferSize %d returning %d (%d (%d %d) %d (%d %d))", sizesP->cmdId, commandSize+containerSize,
commandSize, sizesP->cmdRspSize, commandP->length,
containerSize, sizesP->cmdContainerSize, sizesP->rspContainerSize);
return (commandSize+containerSize);
}