Skip to content

Commit

Permalink
Merge branch 'dev/v202210.01-lts-rx-1.1.2' into 'main'
Browse files Browse the repository at this point in the history
Update the signature extraction

See merge request products/common/rtos/amazon-freertos/lts/iot-reference-rx!140
  • Loading branch information
KazukiMochizuki926 committed Dec 15, 2023
2 parents bff68b7 + ff20642 commit 97ceea6
Showing 1 changed file with 90 additions and 22 deletions.
112 changes: 90 additions & 22 deletions Common/ports/ota_pal/ota_pal.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@
#include "r_fwup_if.h"
#include "r_fwup_private.h"
#include "./src/targets/rx65n/r_flash_rx65n.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/asn1.h"
#include "mbedtls/error.h"

#define MAX_LENGTH 32
#define MAX_SIG_LENGTH 64
#define HALF_SIG_LENGTH MAX_SIG_LENGTH/2

const char OTA_JsonFileSignatureKey[ OTA_FILE_SIG_KEY_STR_MAX_LENGTH ] = "sig-sha256-ecdsa";
static OtaImageState_t OtaImageState;
Expand All @@ -52,6 +59,7 @@ BaseType_t s_first_block_received = pdFALSE;
uint8_t *s_first_ota_blocks[otaconfigMAX_NUM_BLOCKS_REQUEST];

OtaFileContext_t *pOTAFileContext;
int ExtractECDSASignature(const unsigned char *derSignature, size_t derSignatureLength, unsigned char *rawSignature);

OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const pFileContext )
{
Expand Down Expand Up @@ -179,12 +187,12 @@ static OtaPalStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const pFileC
{
OtaPalMainStatus_t eResult = OtaPalUninitialized;
e_fwup_err_t eRet = FWUP_SUCCESS;
int ret;

pOTAFileContext = pFileContext; // store the OTA file context to be used by FWUP verify wrapper
// Buffer to hold the raw ECDSA signature
unsigned char rawSignature[MAX_SIG_LENGTH];

// extract the signature for verification by bootloader
uint8_t sig[64];
uint16_t idx;
pOTAFileContext = pFileContext; // store the OTA file context to be used by FWUP verify wrapper

/*
* C->pxSignature->ucData includes some ASN1 tags.
Expand Down Expand Up @@ -213,26 +221,16 @@ static OtaPalStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const pFileC
return OTA_PAL_COMBINE_ERR( OtaPalSignatureCheckFailed, 0 );
}

// Extract signature ASN1
// SIG(R)
idx = 3;
if (0x21 == pFileContext->pSignature->data[idx++])
{
idx++; /* Skip 0x00 */
}
memcpy(sig, &pFileContext->pSignature->data[idx], 32);

/* SIG(S) */
idx += 32;
idx++;
if (0x21 == pFileContext->pSignature->data[idx++])
{
idx++; /* Skip 0x00 */
}
memcpy(sig+32, &pFileContext->pSignature->data[idx], 32);
if (0 != ExtractECDSASignature(pFileContext->pSignature->data, pFileContext->pSignature->size, rawSignature))
{
eResult = OtaPalBadSignerCert;
LogError( ("Error ECDSASignature extraction\r\n") );
return OTA_PAL_COMBINE_ERR( eResult, 0 );
}

eRet = R_FWUP_WriteImageHeader( FWUP_AREA_BUFFER,
(uint8_t FWUP_FAR *)OTA_JsonFileSignatureKey, sig, 64);
(uint8_t FWUP_FAR *)OTA_JsonFileSignatureKey, rawSignature, MAX_SIG_LENGTH);

if ( FWUP_SUCCESS != eRet )
{
Expand All @@ -242,6 +240,7 @@ static OtaPalStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const pFileC
return OTA_PAL_COMBINE_ERR( eResult, 0 );
}


// Verify the signature
eRet = R_FWUP_VerifyImage(FWUP_AREA_BUFFER);

Expand All @@ -252,7 +251,8 @@ static OtaPalStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const pFileC

return OTA_PAL_COMBINE_ERR( eResult, 0 );
}
else {
else
{
eResult = OtaPalSuccess;
}

Expand Down Expand Up @@ -419,3 +419,71 @@ OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const pFileC
LogDebug( ( "Function called is otaPal_GetPlatformImageState: Platform State is [%d]", ePalState ) );
return ePalState;
}

int ExtractECDSASignature(const unsigned char *derSignature, size_t derSignatureLength, unsigned char *rawSignature)
{
unsigned char *p = (unsigned char*) derSignature;
const unsigned char *end = derSignature + derSignatureLength;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
mbedtls_mpi r, s;

/* Start reusing the process of mbedtls_ecdsa_read_signature_restartable function */

/* Check the parameters. */
configASSERT(derSignature != NULL);
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);

if ( (ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0)
{
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}

if (p + len != end)
{
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
goto cleanup;
}

// Get R,S component
if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 ||
(ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0)
{
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}

/* Finished reusing the process of mbedtls_ecdsa_read_signature_restartable function */

// Convert MPIs to raw byte strings
// The raw ECDSA signature in rawSignature
ret = mbedtls_mpi_write_binary(&r, &rawSignature[0], HALF_SIG_LENGTH);
if (0 != ret)
{
goto cleanup;
}
ret = mbedtls_mpi_write_binary(&s, &rawSignature[HALF_SIG_LENGTH], HALF_SIG_LENGTH);
if (0 != ret)
{
goto cleanup;
}

/* Start reusing the process of mbedtls_ecdsa_read_signature_restartable function */

/* At this point we know that the buffer starts with a valid signature.
* Return 0 if the buffer just contains the signature, and a specific
* error code if the valid signature is followed by more data. */
if (p != end)
ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
cleanup:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);

/* Finished reusing the process of mbedtls_ecdsa_read_signature_restartable function */

return ret;
}

0 comments on commit 97ceea6

Please sign in to comment.