mirror of https://github.com/rusefi/openblt.git
Refs #618. Added support for splitting the XCP seed/key over multiple packets to make larger seed/key values possible, specifically on CAN.
git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@630 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
parent
6345a5433d
commit
5ababf911d
|
@ -81,7 +81,7 @@ static uint16_t XcpLoaderGetOrderedWord(uint8_t const * data);
|
||||||
static bool XcpLoaderSendCmdConnect(void);
|
static bool XcpLoaderSendCmdConnect(void);
|
||||||
static bool XcpLoaderSendCmdGetStatus(uint8_t * session, uint8_t * protectedResources,
|
static bool XcpLoaderSendCmdGetStatus(uint8_t * session, uint8_t * protectedResources,
|
||||||
uint16_t * configId);
|
uint16_t * configId);
|
||||||
static bool XcpLoaderSendCmdGetSeed(uint8_t resource, uint8_t * seed, uint8_t * seedLen);
|
static bool XcpLoaderSendCmdGetSeed(uint8_t resource, uint8_t mode, uint8_t * seed, uint8_t * seedLen);
|
||||||
static bool XcpLoaderSendCmdUnlock(uint8_t const * key, uint8_t keyLen,
|
static bool XcpLoaderSendCmdUnlock(uint8_t const * key, uint8_t keyLen,
|
||||||
uint8_t * protectedResources);
|
uint8_t * protectedResources);
|
||||||
static bool XcpLoaderSendCmdSetMta(uint32_t address);
|
static bool XcpLoaderSendCmdSetMta(uint32_t address);
|
||||||
|
@ -316,10 +316,16 @@ static bool XcpLoaderStart(void)
|
||||||
if ( (protectedResources & XCPPROTECT_RESOURCE_PGM) != 0)
|
if ( (protectedResources & XCPPROTECT_RESOURCE_PGM) != 0)
|
||||||
{
|
{
|
||||||
uint8_t availableResources = 0;
|
uint8_t availableResources = 0;
|
||||||
uint8_t seed[XCPLOADER_PACKET_SIZE_MAX-2] = { 0 };
|
uint8_t seed[256] = { 0 };
|
||||||
uint8_t seedLen = 0;
|
uint8_t *seedPtr = &seed[0];
|
||||||
uint8_t key[XCPLOADER_PACKET_SIZE_MAX-2] = { 0 };
|
uint8_t seedTotalLen = 0;
|
||||||
uint8_t keyLen = 0;
|
uint8_t seedRemainingLen = 0;
|
||||||
|
uint8_t key[256] = { 0 };
|
||||||
|
uint8_t keyTotalLen = 0;
|
||||||
|
uint8_t keyRemainingLen = 0;
|
||||||
|
uint8_t keyCurrentLen = 0;
|
||||||
|
uint8_t *keyPtr = &key[0];
|
||||||
|
|
||||||
/* Make sure the XCP protection module contains an unlock algorithm for the
|
/* Make sure the XCP protection module contains an unlock algorithm for the
|
||||||
* programming resource.
|
* programming resource.
|
||||||
*/
|
*/
|
||||||
|
@ -340,22 +346,41 @@ static bool XcpLoaderStart(void)
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Request the seed for unlocking the programming resources. */
|
/* Request (first part of) the seed for unlocking the programming resources. */
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
if (!XcpLoaderSendCmdGetSeed(XCPPROTECT_RESOURCE_PGM, seed, &seedLen))
|
if (!XcpLoaderSendCmdGetSeed(XCPPROTECT_RESOURCE_PGM, 0, seedPtr, &seedRemainingLen))
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* store the total seed length */
|
||||||
|
seedTotalLen = seedRemainingLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Check if more parts of the seed need to be requested. */
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
while (seedRemainingLen > (xcpMaxDto - 2))
|
||||||
|
{
|
||||||
|
/* update the seed pointer for the next part */
|
||||||
|
seedPtr += (xcpMaxDto - 2);
|
||||||
|
if (!XcpLoaderSendCmdGetSeed(XCPPROTECT_RESOURCE_PGM, 1, seedPtr, &seedRemainingLen))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Only continue with resource unlock operation if not already unlocked, which
|
/* Only continue with resource unlock operation if not already unlocked, which
|
||||||
* is indicated by a seed length of 0.
|
* is indicated by a seed length of 0.
|
||||||
*/
|
*/
|
||||||
if ( (result) && (seedLen > 0) )
|
if ( (result) && (seedTotalLen > 0) )
|
||||||
{
|
{
|
||||||
/* Compute the key using the XCP protection module. */
|
/* Compute the key using the XCP protection module. */
|
||||||
if (!XCPProtectComputeKeyFromSeed(XCPPROTECT_RESOURCE_PGM, seedLen, seed,
|
if (!XCPProtectComputeKeyFromSeed(XCPPROTECT_RESOURCE_PGM, seedTotalLen, seed,
|
||||||
&keyLen, key))
|
&keyTotalLen, key))
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
@ -363,13 +388,33 @@ static bool XcpLoaderStart(void)
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
uint8_t currentlyProtectedResources = 0;
|
uint8_t currentlyProtectedResources = 0;
|
||||||
/* Send the key to unlock the resource. */
|
|
||||||
if (!XcpLoaderSendCmdUnlock(key, keyLen, ¤tlyProtectedResources))
|
/* Initialize remaining length */
|
||||||
|
keyRemainingLen = keyTotalLen;
|
||||||
|
|
||||||
|
/* Send the key to unlock the resource */
|
||||||
|
while (keyRemainingLen > 0)
|
||||||
|
{
|
||||||
|
/* Determine how many key bytes are about to be sent. */
|
||||||
|
keyCurrentLen = keyRemainingLen;
|
||||||
|
if (keyCurrentLen > (xcpMaxCto - 2))
|
||||||
|
{
|
||||||
|
keyCurrentLen = (xcpMaxCto - 2);
|
||||||
|
}
|
||||||
|
/* The the (possible partial) unlock command. */
|
||||||
|
if (!XcpLoaderSendCmdUnlock(keyPtr, keyRemainingLen, ¤tlyProtectedResources))
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
/* Update key pointer and the remaining length */
|
||||||
|
keyRemainingLen -= keyCurrentLen;
|
||||||
|
keyPtr += keyCurrentLen;
|
||||||
|
/* Check if the key was now completely sent. */
|
||||||
|
if (keyRemainingLen == 0)
|
||||||
|
{
|
||||||
/* Double-check that the programming resource is now unlocked. */
|
/* Double-check that the programming resource is now unlocked. */
|
||||||
else if ((currentlyProtectedResources & XCPPROTECT_RESOURCE_PGM) != 0)
|
if ((currentlyProtectedResources & XCPPROTECT_RESOURCE_PGM) != 0)
|
||||||
{
|
{
|
||||||
/* Programming resource unlock operation failed. */
|
/* Programming resource unlock operation failed. */
|
||||||
result = false;
|
result = false;
|
||||||
|
@ -377,6 +422,8 @@ static bool XcpLoaderStart(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Place the target in programming mode if connected. */
|
/* Place the target in programming mode if connected. */
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
@ -825,14 +872,17 @@ static bool XcpLoaderSendCmdGetStatus(uint8_t * session, uint8_t * protectedReso
|
||||||
/************************************************************************************//**
|
/************************************************************************************//**
|
||||||
** \brief Sends the XCP Get Seed command.
|
** \brief Sends the XCP Get Seed command.
|
||||||
** \param resource The resource to unlock (XCPPROTECT_RESOURCE_xxx).
|
** \param resource The resource to unlock (XCPPROTECT_RESOURCE_xxx).
|
||||||
|
** \param mode 0 for the first part of the seed, 1 for the remaining part.
|
||||||
** \param seed Pointer to byte array where the received seed is stored.
|
** \param seed Pointer to byte array where the received seed is stored.
|
||||||
** \param seedLen Length of the seed in bytes.
|
** \param seedLen Length of the seed in bytes.
|
||||||
** \return True if successful, false otherwise.
|
** \return True if successful, false otherwise.
|
||||||
**
|
**
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
static bool XcpLoaderSendCmdGetSeed(uint8_t resource, uint8_t * seed, uint8_t * seedLen)
|
static bool XcpLoaderSendCmdGetSeed(uint8_t resource, uint8_t mode, uint8_t * seed,
|
||||||
|
uint8_t * seedLen)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
uint8_t currentSeedLen;
|
||||||
tXcpTransportPacket cmdPacket;
|
tXcpTransportPacket cmdPacket;
|
||||||
tXcpTransportPacket resPacket;
|
tXcpTransportPacket resPacket;
|
||||||
|
|
||||||
|
@ -857,12 +907,7 @@ static bool XcpLoaderSendCmdGetSeed(uint8_t resource, uint8_t * seed, uint8_t *
|
||||||
result = true;
|
result = true;
|
||||||
/* Prepare the command packet. */
|
/* Prepare the command packet. */
|
||||||
cmdPacket.data[0] = XCPLOADER_CMD_GET_SEED;
|
cmdPacket.data[0] = XCPLOADER_CMD_GET_SEED;
|
||||||
/* Always use mode 0 because only seeds up to 48-bit are supported currently.
|
cmdPacket.data[1] = mode;
|
||||||
* This fits in 6-bytes, making it work with the all currently supported transport
|
|
||||||
* layers. CAN is the limiting one, because the max packet length is 8-bytes for
|
|
||||||
* this transport layer.
|
|
||||||
*/
|
|
||||||
cmdPacket.data[1] = 0;
|
|
||||||
cmdPacket.data[2] = resource;
|
cmdPacket.data[2] = resource;
|
||||||
cmdPacket.len = 3;
|
cmdPacket.len = 3;
|
||||||
/* Send the packet. */
|
/* Send the packet. */
|
||||||
|
@ -885,25 +930,23 @@ static bool XcpLoaderSendCmdGetSeed(uint8_t resource, uint8_t * seed, uint8_t *
|
||||||
}
|
}
|
||||||
/* Extract and store the seed. */
|
/* Extract and store the seed. */
|
||||||
if (result)
|
if (result)
|
||||||
{
|
|
||||||
/* Make sure the seed length is valid. */
|
|
||||||
if (resPacket.data[1] > (xcpMaxCto - 2))
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* Store the seed length. */
|
/* Store the seed length. */
|
||||||
*seedLen = resPacket.data[1];
|
*seedLen = resPacket.data[1];
|
||||||
/* Store the seed. */
|
/* Determine the number of seed bytes in the current response */
|
||||||
for (uint8_t idx = 0; idx < *seedLen; idx++)
|
currentSeedLen = *seedLen;
|
||||||
|
if (currentSeedLen > (xcpMaxCto - 2))
|
||||||
|
{
|
||||||
|
currentSeedLen = (xcpMaxCto - 2);
|
||||||
|
}
|
||||||
|
/* Store the seed bytes. */
|
||||||
|
for (uint8_t idx = 0; idx < currentSeedLen; idx++)
|
||||||
{
|
{
|
||||||
seed[idx] = resPacket.data[idx + 2];
|
seed[idx] = resPacket.data[idx + 2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Give the result back to the caller. */
|
/* Give the result back to the caller. */
|
||||||
return result;
|
return result;
|
||||||
} /*** end of XcpLoaderSendCmdGetSeed ***/
|
} /*** end of XcpLoaderSendCmdGetSeed ***/
|
||||||
|
@ -921,6 +964,7 @@ static bool XcpLoaderSendCmdUnlock(uint8_t const * key, uint8_t keyLen,
|
||||||
uint8_t * protectedResources)
|
uint8_t * protectedResources)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
uint8_t keyCurrentLen;
|
||||||
tXcpTransportPacket cmdPacket;
|
tXcpTransportPacket cmdPacket;
|
||||||
tXcpTransportPacket resPacket;
|
tXcpTransportPacket resPacket;
|
||||||
|
|
||||||
|
@ -928,23 +972,29 @@ static bool XcpLoaderSendCmdUnlock(uint8_t const * key, uint8_t keyLen,
|
||||||
assert(xcpSettings.transport != NULL);
|
assert(xcpSettings.transport != NULL);
|
||||||
assert(key != NULL);
|
assert(key != NULL);
|
||||||
assert(keyLen > 0);
|
assert(keyLen > 0);
|
||||||
assert(keyLen <= (xcpMaxCto - 2));
|
|
||||||
assert(protectedResources != NULL);
|
assert(protectedResources != NULL);
|
||||||
|
|
||||||
/* Only continue with a valid transport layer and parameters. */
|
/* Only continue with a valid transport layer and parameters. */
|
||||||
if ( (xcpSettings.transport != NULL) && (key != NULL) && (keyLen > 0) &&
|
if ( (xcpSettings.transport != NULL) && (key != NULL) && (keyLen > 0) &&
|
||||||
(keyLen <= (xcpMaxCto - 2)) && (protectedResources != NULL) ) /*lint !e774 */
|
(protectedResources != NULL) ) /*lint !e774 */
|
||||||
{
|
{
|
||||||
/* Init the result value to okay and only set it to error when a problem occurred. */
|
/* Init the result value to okay and only set it to error when a problem occurred. */
|
||||||
result = true;
|
result = true;
|
||||||
/* Prepare the command packet. */
|
/* Prepare the command packet. */
|
||||||
cmdPacket.data[0] = XCPLOADER_CMD_UNLOCK;
|
cmdPacket.data[0] = XCPLOADER_CMD_UNLOCK;
|
||||||
cmdPacket.data[1] = keyLen;
|
cmdPacket.data[1] = keyLen;
|
||||||
for (uint8_t idx = 0; idx < keyLen; idx++)
|
/* Determine number of key bytes for the packet. */
|
||||||
|
keyCurrentLen = keyLen;
|
||||||
|
if (keyCurrentLen > (xcpMaxCto - 2))
|
||||||
|
{
|
||||||
|
keyCurrentLen = xcpMaxCto - 2;
|
||||||
|
}
|
||||||
|
/* Copy key bytes. */
|
||||||
|
for (uint8_t idx = 0; idx < keyCurrentLen; idx++)
|
||||||
{
|
{
|
||||||
cmdPacket.data[idx + 2] = key[idx];
|
cmdPacket.data[idx + 2] = key[idx];
|
||||||
}
|
}
|
||||||
cmdPacket.len = keyLen + 2;
|
cmdPacket.len = keyCurrentLen + 2;
|
||||||
/* Send the packet. */
|
/* Send the packet. */
|
||||||
if (!xcpSettings.transport->SendPacket(&cmdPacket, &resPacket,
|
if (!xcpSettings.transport->SendPacket(&cmdPacket, &resPacket,
|
||||||
xcpSettings.timeoutT1))
|
xcpSettings.timeoutT1))
|
||||||
|
|
Binary file not shown.
|
@ -499,6 +499,21 @@
|
||||||
#error "BOOT_XCP_PACKET_RECEIVED_HOOK must be 0 or 1"
|
#error "BOOT_XCP_PACKET_RECEIVED_HOOK must be 0 or 1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOT_XCP_SEED_MAX_LEN
|
||||||
|
#define BOOT_XCP_SEED_MAX_LEN (64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (BOOT_XCP_SEED_MAX_LEN <= 0)
|
||||||
|
#error "BOOT_XCP_SEED_MAX_LEN must be > 0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOT_XCP_KEY_MAX_LEN
|
||||||
|
#define BOOT_XCP_KEY_MAX_LEN (64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (BOOT_XCP_KEY_MAX_LEN <= 0)
|
||||||
|
#error "BOOT_XCP_KEY_MAX_LEN must be > 0"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* PLAUSIBILITY_H */
|
#endif /* PLAUSIBILITY_H */
|
||||||
/*********************************** end of plausibility.h *****************************/
|
/*********************************** end of plausibility.h *****************************/
|
||||||
|
|
|
@ -915,7 +915,19 @@ static void XcpCmdBuildCheckSum(blt_int8u *data)
|
||||||
static void XcpCmdGetSeed(blt_int8u *data)
|
static void XcpCmdGetSeed(blt_int8u *data)
|
||||||
{
|
{
|
||||||
blt_int8u resourceOK;
|
blt_int8u resourceOK;
|
||||||
|
/* made seed buffer static to lower stack load */
|
||||||
|
static blt_int8u seedBuffer[XCP_SEED_MAX_LEN];
|
||||||
|
static blt_int8u seedRemainderLen = 0;
|
||||||
|
static blt_int8u *seedCurrentPtr;
|
||||||
|
static blt_bool sequenceInProgress = BLT_FALSE;
|
||||||
|
blt_int8u seedCurrentLen;
|
||||||
|
|
||||||
|
/* set packet id to command response packet */
|
||||||
|
xcpInfo.ctoData[0] = XCP_PID_RES;
|
||||||
|
|
||||||
|
/* validate requested resource in case the mode flag equals 0 */
|
||||||
|
if (data[1] == 0)
|
||||||
|
{
|
||||||
/* init resource check variable as if an illegal resource is requested */
|
/* init resource check variable as if an illegal resource is requested */
|
||||||
resourceOK = 0;
|
resourceOK = 0;
|
||||||
|
|
||||||
|
@ -958,25 +970,65 @@ static void XcpCmdGetSeed(blt_int8u *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store resource for which the seed/key sequence is started */
|
/* check if the resource is already unlocked */
|
||||||
xcpInfo.s_n_k_resource = data[2];
|
if ((xcpInfo.protection & data[2]) == 0)
|
||||||
|
|
||||||
/* set packet id to command response packet */
|
|
||||||
xcpInfo.ctoData[0] = XCP_PID_RES;
|
|
||||||
|
|
||||||
/* request the seed from the application */
|
|
||||||
xcpInfo.ctoData[1] = XcpGetSeed(xcpInfo.s_n_k_resource, &xcpInfo.ctoData[2]);
|
|
||||||
|
|
||||||
/* seed cannot be longer than XCP_CTO_PACKET_LEN-2 */
|
|
||||||
if (xcpInfo.ctoData[1] > (XCP_CTO_PACKET_LEN-2))
|
|
||||||
{
|
{
|
||||||
/* seed length is too long */
|
/* set the seed length to 0 to indicate that the resource is already unlocked */
|
||||||
XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
|
xcpInfo.ctoData[1] = 0;
|
||||||
|
/* set packet length */
|
||||||
|
xcpInfo.ctoLen = 2;
|
||||||
|
/* no need to continue processing */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* store resource for which the seed/key sequence is started */
|
||||||
|
xcpInfo.s_n_k_resource = data[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process the mode flag. 0 is first part of the seed, 1 is remainder of the seed */
|
||||||
|
if (data[1] == 0)
|
||||||
|
{
|
||||||
|
/* set flag that a seed reading sequence is now in progress */
|
||||||
|
sequenceInProgress = BLT_TRUE;
|
||||||
|
/* obtain the seed and store it in the buffer */
|
||||||
|
seedRemainderLen = XcpGetSeed(xcpInfo.s_n_k_resource, seedBuffer);
|
||||||
|
/* protect against buffer overrun */
|
||||||
|
ASSERT_RT(seedRemainderLen <= XCP_SEED_MAX_LEN);
|
||||||
|
/* set seed pointer */
|
||||||
|
seedCurrentPtr = &seedBuffer[0];
|
||||||
|
}
|
||||||
|
/* seed remainder is requested */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this is only allowed if a sequence is in progress */
|
||||||
|
if (sequenceInProgress == BLT_FALSE)
|
||||||
|
{
|
||||||
|
/* invalid sequence */
|
||||||
|
XcpSetCtoError(XCP_ERR_SEQUENCE);
|
||||||
|
/* reset seed/key resource variable for possible next unlock */
|
||||||
|
xcpInfo.s_n_k_resource = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* determine number of seed bytes that fit in the first response */
|
||||||
|
seedCurrentLen = seedRemainderLen;
|
||||||
|
if (seedCurrentLen > (XCP_CTO_PACKET_LEN-2))
|
||||||
|
{
|
||||||
|
seedCurrentLen = XCP_CTO_PACKET_LEN-2;
|
||||||
|
}
|
||||||
|
/* store the first part of the seed in the response */
|
||||||
|
CpuMemCopy((blt_addr)(&xcpInfo.ctoData[2]), (blt_addr)seedCurrentPtr, seedCurrentLen);
|
||||||
|
xcpInfo.ctoData[1] = seedRemainderLen;
|
||||||
|
/* update control variables */
|
||||||
|
seedRemainderLen -= seedCurrentLen;
|
||||||
|
seedCurrentPtr += seedCurrentLen;
|
||||||
|
/* reset sequence flag at the end of the sequence */
|
||||||
|
if (seedRemainderLen == 0)
|
||||||
|
{
|
||||||
|
sequenceInProgress = BLT_FALSE;
|
||||||
|
}
|
||||||
/* set packet length */
|
/* set packet length */
|
||||||
xcpInfo.ctoLen = xcpInfo.ctoData[1] + 2;
|
xcpInfo.ctoLen = seedCurrentLen + 2;
|
||||||
} /*** end of XcpCmdGetSeed ***/
|
} /*** end of XcpCmdGetSeed ***/
|
||||||
|
|
||||||
|
|
||||||
|
@ -989,41 +1041,82 @@ static void XcpCmdGetSeed(blt_int8u *data)
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
static void XcpCmdUnlock(blt_int8u *data)
|
static void XcpCmdUnlock(blt_int8u *data)
|
||||||
{
|
{
|
||||||
/* key cannot be longer than XCP_CTO_PACKET_LEN-2 */
|
/* made key buffer static to lower stack load */
|
||||||
if (data[1] > (XCP_CTO_PACKET_LEN-2))
|
static blt_int8u keyBuffer[XCP_KEY_MAX_LEN];
|
||||||
|
static blt_int8u keyPreviousRemainder = 0;
|
||||||
|
static blt_int8u keyTotalLen = 0;
|
||||||
|
static blt_int8u *keyCurrentPtr;
|
||||||
|
static blt_int8u keyReceivedLen = 0;
|
||||||
|
blt_int8u keyCurrentLen;
|
||||||
|
|
||||||
|
/* verify that the key will actually fit in the buffer */
|
||||||
|
if (data[1] > XCP_KEY_MAX_LEN)
|
||||||
{
|
{
|
||||||
/* key is too long incorrect */
|
/* reset previous remainder for the next loop iteration */
|
||||||
XcpSetCtoError(XCP_ERR_SEQUENCE);
|
keyPreviousRemainder = 0;
|
||||||
|
/* key is too long */
|
||||||
|
XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
|
||||||
|
/* reset seed/key resource variable for possible next unlock */
|
||||||
|
xcpInfo.s_n_k_resource = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* is this the start of a key reception? the first unlock message contains the total
|
||||||
|
* length of the key and subsequent messages the remainder length. if the received
|
||||||
|
* length is >= than the previously received remainder, it must be the reception
|
||||||
|
* start of a new key.
|
||||||
|
*/
|
||||||
|
if (data[1] >= keyPreviousRemainder)
|
||||||
|
{
|
||||||
|
/* store the total length of the key */
|
||||||
|
keyTotalLen = data[1];
|
||||||
|
/* initialize pointer to key reception buffer */
|
||||||
|
keyCurrentPtr = &keyBuffer[0];
|
||||||
|
/* reset number of received key bytes */
|
||||||
|
keyReceivedLen = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* store length / remainder for checking during the next iteration */
|
||||||
|
keyPreviousRemainder = data[1];
|
||||||
|
/* determine how many key bytes were received */
|
||||||
|
keyCurrentLen = data[1];
|
||||||
|
if (keyCurrentLen > (XCP_CTO_PACKET_LEN-2))
|
||||||
|
{
|
||||||
|
keyCurrentLen = XCP_CTO_PACKET_LEN-2;
|
||||||
|
}
|
||||||
|
/* store the received key bytes to the buffer */
|
||||||
|
CpuMemCopy((blt_addr)keyCurrentPtr, (blt_addr)(&data[2]), keyCurrentLen);
|
||||||
|
/* update control variables */
|
||||||
|
keyCurrentPtr += keyCurrentLen;
|
||||||
|
keyReceivedLen += keyCurrentLen;
|
||||||
|
/* check if the entire key was received */
|
||||||
|
if (keyReceivedLen >= keyTotalLen)
|
||||||
|
{
|
||||||
|
/* reset previous remainder for the next loop iteration */
|
||||||
|
keyPreviousRemainder = 0;
|
||||||
/* verify the key */
|
/* verify the key */
|
||||||
if (XcpVerifyKey(xcpInfo.s_n_k_resource, &data[2], data[1]) == 0)
|
if (XcpVerifyKey(xcpInfo.s_n_k_resource, keyBuffer, keyTotalLen) == 0)
|
||||||
{
|
{
|
||||||
/* invalid key so inform the master and do a disconnect */
|
/* invalid key so inform the master and do a disconnect */
|
||||||
XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
|
XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
|
||||||
|
|
||||||
/* indicate that the xcp connection is disconnected */
|
/* indicate that the xcp connection is disconnected */
|
||||||
xcpInfo.connected = 0;
|
xcpInfo.connected = 0;
|
||||||
|
|
||||||
/* enable resource protection */
|
|
||||||
XcpProtectResources();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* key correct so unlock the resource */
|
|
||||||
xcpInfo.protection &= ~xcpInfo.s_n_k_resource;
|
|
||||||
|
|
||||||
/* reset seed/key resource variable for possible next unlock */
|
/* reset seed/key resource variable for possible next unlock */
|
||||||
xcpInfo.s_n_k_resource = 0;
|
xcpInfo.s_n_k_resource = 0;
|
||||||
|
/* enable resource protection */
|
||||||
|
XcpProtectResources();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* key correct so unlock the resource */
|
||||||
|
xcpInfo.protection &= ~xcpInfo.s_n_k_resource;
|
||||||
|
/* reset seed/key resource variable for possible next unlock */
|
||||||
|
xcpInfo.s_n_k_resource = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* set packet id to command response packet */
|
/* set packet id to command response packet */
|
||||||
xcpInfo.ctoData[0] = XCP_PID_RES;
|
xcpInfo.ctoData[0] = XCP_PID_RES;
|
||||||
|
|
||||||
/* report the current resource protection */
|
/* report the current resource protection */
|
||||||
xcpInfo.ctoData[1] = xcpInfo.protection;
|
xcpInfo.ctoData[1] = xcpInfo.protection;
|
||||||
|
|
||||||
/* set packet length */
|
/* set packet length */
|
||||||
xcpInfo.ctoLen = 2;
|
xcpInfo.ctoLen = 2;
|
||||||
} /*** end of XcpCmdUnlock ***/
|
} /*** end of XcpCmdUnlock ***/
|
||||||
|
|
|
@ -240,6 +240,11 @@
|
||||||
/** \brief Use user defined algorithm. */
|
/** \brief Use user defined algorithm. */
|
||||||
#define XCP_CS_USER (0xff)
|
#define XCP_CS_USER (0xff)
|
||||||
|
|
||||||
|
/** \brief Maximum number of bytes of a seed for the seed/key security feature. */
|
||||||
|
#define XCP_SEED_MAX_LEN (BOOT_XCP_SEED_MAX_LEN)
|
||||||
|
/** \brief Maximum number of bytes of a key for the seed/key security feature. */
|
||||||
|
#define XCP_KEY_MAX_LEN (BOOT_XCP_KEY_MAX_LEN)
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Function prototypes
|
* Function prototypes
|
||||||
|
|
Loading…
Reference in New Issue