Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworked Cmac hash computation for lower memory consumption #677

Merged
merged 5 commits into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions src/mac/LoRaMacCrypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,10 @@ static LoRaMacCryptoStatus_t FOptsEncrypt( uint16_t size, uint32_t address, uint
*/
static LoRaMacCryptoStatus_t ComputeCmac( uint8_t* msg, uint16_t len, KeyIdentifier_t keyID, uint32_t* cmac )
{
if( SecureElementComputeAesCmac( msg, len, keyID, cmac ) != SECURE_ELEMENT_SUCCESS )
struct se_block part;
part.buffer = msg;
part.size = len;
if( SecureElementComputeAesCmacParts( &part, 1, keyID, cmac ) != SECURE_ELEMENT_SUCCESS )
{
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
}
Expand Down Expand Up @@ -494,16 +497,18 @@ static LoRaMacCryptoStatus_t ComputeCmacB0( uint8_t* msg, uint16_t len, KeyIdent
return LORAMAC_CRYPTO_ERROR_BUF_SIZE;
}

uint8_t micBuff[CRYPTO_BUFFER_SIZE];
memset1( micBuff, 0, CRYPTO_BUFFER_SIZE );
uint8_t micBuff[MIC_BLOCK_BX_SIZE];

// Initialize the first Block
PrepareB0( len, keyID, isAck, dir, devAddr, fCnt, micBuff );

// Copy the given data to the mic computation buffer
memcpy1( ( micBuff + MIC_BLOCK_BX_SIZE ), msg, len );
struct se_block parts[2];
parts[0].buffer = micBuff;
parts[0].size = sizeof( micBuff );
parts[1].buffer = msg;
parts[1].size = len;

if( SecureElementComputeAesCmac( micBuff, ( len + MIC_BLOCK_BX_SIZE ), keyID, cmac ) != SECURE_ELEMENT_SUCCESS )
if( SecureElementComputeAesCmacParts( parts, 2, keyID, cmac ) != SECURE_ELEMENT_SUCCESS )
{
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
}
Expand Down Expand Up @@ -642,16 +647,18 @@ static LoRaMacCryptoStatus_t ComputeCmacB1( uint8_t* msg, uint16_t len, KeyIdent
return LORAMAC_CRYPTO_ERROR_BUF_SIZE;
}

uint8_t micBuff[CRYPTO_BUFFER_SIZE];
memset1( micBuff, 0, CRYPTO_BUFFER_SIZE );
uint8_t micBuff[MIC_BLOCK_BX_SIZE];

// Initialize the first Block
PrepareB1( len, keyID, isAck, txDr, txCh, devAddr, fCntUp, micBuff );

// Copy the given data to the mic computation buffer
memcpy1( ( micBuff + MIC_BLOCK_BX_SIZE ), msg, len );
struct se_block parts[2];
parts[0].buffer = micBuff;
parts[0].size = sizeof( micBuff );
parts[1].buffer = msg;
parts[1].size = len;

if( SecureElementComputeAesCmac( micBuff, ( len + MIC_BLOCK_BX_SIZE ), keyID, cmac ) != SECURE_ELEMENT_SUCCESS )
if( SecureElementComputeAesCmacParts( parts, 2, keyID, cmac ) != SECURE_ELEMENT_SUCCESS )
{
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
}
Expand Down
12 changes: 8 additions & 4 deletions src/mac/secure-element.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,19 @@ void* SecureElementGetNvmCtx( size_t* seNvmCtxSize );
SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key );

/*!
* Computes a CMAC
* Computes a CMAC of a message given in parts
*
* \param[IN] buffer - Data buffer
* \param[IN] size - Data buffer size
* \param[IN] buffers - Data buffers
* \param[IN] numparts - Number of buffers
* \param[IN] keyID - Key identifier to determine the AES key to be used
* \param[OUT] cmac - Computed cmac
* \retval - Status of the operation
*/
SecureElementStatus_t SecureElementComputeAesCmac( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac );
struct se_block {
uint8_t *buffer;
uint16_t size;
};
SecureElementStatus_t SecureElementComputeAesCmacParts( struct se_block *parts, uint16_t numparts, KeyIdentifier_t keyID, uint32_t* cmac );

/*!
* Verifies a CMAC (computes and compare with expected cmac)
Expand Down
37 changes: 29 additions & 8 deletions src/peripherals/soft-se/soft-se.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,17 @@ SecureElementStatus_t GetKeyByID( KeyIdentifier_t keyID, Key_t** keyItem )
}

/*
* Computes a CMAC
* Computes a CMAC of a message given in parts
*
* \param[IN] buffer - Data buffer
* \param[IN] size - Data buffer size
* \param[IN] parts - Data buffers
* \param[IN] num - Number of buffers
* \param[IN] keyID - Key identifier to determine the AES key to be used
* \param[OUT] cmac - Computed cmac
* \retval - Status of the operation
*/
SecureElementStatus_t ComputeCmac( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac )
SecureElementStatus_t ComputeCmacParts( struct se_block *parts, uint16_t num, KeyIdentifier_t keyID, uint32_t* cmac )
{
if( buffer == NULL || cmac == NULL )
if( parts == NULL || cmac == NULL || num == 0 )
{
return SECURE_ELEMENT_ERROR_NPE;
}
Expand All @@ -126,7 +126,11 @@ SecureElementStatus_t ComputeCmac( uint8_t* buffer, uint16_t size, KeyIdentifier
{
AES_CMAC_SetKey( SeNvmCtx.AesCmacCtx, keyItem->KeyValue );

AES_CMAC_Update( SeNvmCtx.AesCmacCtx, buffer, size );
for ( size_t i = 0; i < num; i++ )
{
if ( parts[i].buffer == NULL || parts[i].size == 0 ) continue;
AES_CMAC_Update( SeNvmCtx.AesCmacCtx, parts[i].buffer, parts[i].size );
}

AES_CMAC_Final( Cmac, SeNvmCtx.AesCmacCtx );

Expand All @@ -137,6 +141,23 @@ SecureElementStatus_t ComputeCmac( uint8_t* buffer, uint16_t size, KeyIdentifier
return retval;
}

/*
* Computes a CMAC
*
* \param[IN] buffer - Data buffer
* \param[IN] size - Data buffer size
* \param[IN] keyID - Key identifier to determine the AES key to be used
* \param[OUT] cmac - Computed cmac
* \retval - Status of the operation
*/
SecureElementStatus_t ComputeCmac( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac )
{
struct se_block part;
part.buffer = buffer;
part.size = size;
return ComputeCmacParts( &part, 1, keyID, cmac );
}

/*
* Dummy callback in case if the user provides NULL function pointer
*/
Expand Down Expand Up @@ -244,15 +265,15 @@ SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key )
return SECURE_ELEMENT_ERROR_INVALID_KEY_ID;
}

SecureElementStatus_t SecureElementComputeAesCmac( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac )
SecureElementStatus_t SecureElementComputeAesCmacParts( struct se_block *parts, uint16_t num, KeyIdentifier_t keyID, uint32_t* cmac )
{
if( keyID >= LORAMAC_CRYPTO_MULITCAST_KEYS )
{
//Never accept multicast key identifier for cmac computation
return SECURE_ELEMENT_ERROR_INVALID_KEY_ID;
}

return ComputeCmac( buffer, size, keyID, cmac );
return ComputeCmacParts( parts, num, keyID, cmac );
}

SecureElementStatus_t SecureElementVerifyAesCmac( uint8_t* buffer, uint16_t size, uint32_t expectedCmac, KeyIdentifier_t keyID )
Expand Down