277 lines
7.8 KiB
C
Executable File
277 lines
7.8 KiB
C
Executable File
/*
|
|
* Amazon FreeRTOS Crypto V1.0.1
|
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* http://aws.amazon.com/freertos
|
|
* http://www.FreeRTOS.org
|
|
*/
|
|
|
|
|
|
/* FreeRTOS includes. */
|
|
#include "FreeRTOS.h"
|
|
#include "FreeRTOSIPConfig.h"
|
|
#include "aws_crypto.h"
|
|
|
|
#ifndef WOLF_AWSTLS
|
|
|
|
/* mbedTLS includes. */
|
|
#include "mbedtls/config.h"
|
|
#include "mbedtls/platform.h"
|
|
#include "mbedtls/sha256.h"
|
|
#include "mbedtls/sha1.h"
|
|
#include "mbedtls/pk.h"
|
|
#include "mbedtls/x509_crt.h"
|
|
|
|
/* C runtime includes. */
|
|
#include <string.h>
|
|
|
|
/**
|
|
* @brief Internal signature verification context structure
|
|
*/
|
|
typedef struct SignatureVerificationState
|
|
{
|
|
BaseType_t xAsymmetricAlgorithm;
|
|
BaseType_t xHashAlgorithm;
|
|
mbedtls_sha1_context xSHA1Context;
|
|
mbedtls_sha256_context xSHA256Context;
|
|
} SignatureVerificationState_t, * SignatureVerificationStatePtr_t;
|
|
|
|
/*
|
|
* Helper routines
|
|
*/
|
|
|
|
/**
|
|
* @brief Implements libc calloc semantics using the FreeRTOS heap
|
|
*/
|
|
static void * prvCalloc( size_t xNmemb,
|
|
size_t xSize )
|
|
{
|
|
void * pvNew = pvPortMalloc( xNmemb * xSize );
|
|
|
|
if( NULL != pvNew )
|
|
{
|
|
memset( pvNew, 0, xNmemb * xSize );
|
|
}
|
|
|
|
return pvNew;
|
|
}
|
|
|
|
/**
|
|
* @brief Verifies a cryptographic signature based on the signer
|
|
* certificate, hash algorithm, and the data that was signed.
|
|
*/
|
|
static BaseType_t prvVerifySignature( char * pcSignerCertificate,
|
|
size_t xSignerCertificateLength,
|
|
BaseType_t xHashAlgorithm,
|
|
uint8_t * pucHash,
|
|
size_t xHashLength,
|
|
uint8_t * pucSignature,
|
|
size_t xSignatureLength )
|
|
{
|
|
BaseType_t xResult = pdTRUE;
|
|
mbedtls_x509_crt xCertCtx;
|
|
mbedtls_md_type_t xMbedHashAlg = MBEDTLS_MD_SHA256;
|
|
|
|
|
|
memset( &xCertCtx, 0, sizeof( mbedtls_x509_crt ) );
|
|
|
|
/*
|
|
* Map the hash algorithm
|
|
*/
|
|
if( cryptoHASH_ALGORITHM_SHA1 == xHashAlgorithm )
|
|
{
|
|
xMbedHashAlg = MBEDTLS_MD_SHA1;
|
|
}
|
|
|
|
/*
|
|
* Decode and create a certificate context
|
|
*/
|
|
mbedtls_x509_crt_init( &xCertCtx );
|
|
|
|
if( 0 != mbedtls_x509_crt_parse(
|
|
&xCertCtx, ( const unsigned char * ) pcSignerCertificate, xSignerCertificateLength ) )
|
|
{
|
|
xResult = pdFALSE;
|
|
}
|
|
|
|
/*
|
|
* Verify the signature using the public key from the decoded certificate
|
|
*/
|
|
if( pdTRUE == xResult )
|
|
{
|
|
if( 0 != mbedtls_pk_verify(
|
|
&xCertCtx.pk,
|
|
xMbedHashAlg,
|
|
pucHash,
|
|
xHashLength,
|
|
pucSignature,
|
|
xSignatureLength ) )
|
|
{
|
|
xResult = pdFALSE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Clean-up
|
|
*/
|
|
mbedtls_x509_crt_free( &xCertCtx );
|
|
|
|
return xResult;
|
|
}
|
|
|
|
/*
|
|
* Interface routines
|
|
*/
|
|
|
|
/**
|
|
* @brief Overrides CRT heap callouts to use FreeRTOS instead
|
|
*/
|
|
void CRYPTO_ConfigureHeap( void )
|
|
{
|
|
/*
|
|
* Ensure that the FreeRTOS heap is used
|
|
*/
|
|
mbedtls_platform_set_calloc_free( prvCalloc, vPortFree ); /*lint !e534 This function always return 0. */
|
|
}
|
|
|
|
/**
|
|
* @brief Creates signature verification context.
|
|
*/
|
|
BaseType_t CRYPTO_SignatureVerificationStart( void ** ppvContext,
|
|
BaseType_t xAsymmetricAlgorithm,
|
|
BaseType_t xHashAlgorithm )
|
|
{
|
|
BaseType_t xResult = pdTRUE;
|
|
SignatureVerificationStatePtr_t pxCtx = NULL;
|
|
|
|
/*
|
|
* Allocate the context
|
|
*/
|
|
if( NULL == ( pxCtx = ( SignatureVerificationStatePtr_t ) pvPortMalloc(
|
|
sizeof( *pxCtx ) ) ) ) /*lint !e9087 Allow casting void* to other types. */
|
|
{
|
|
xResult = pdFALSE;
|
|
}
|
|
|
|
if( pdTRUE == xResult )
|
|
{
|
|
*ppvContext = pxCtx;
|
|
|
|
/*
|
|
* Store the algorithm identifiers
|
|
*/
|
|
pxCtx->xAsymmetricAlgorithm = xAsymmetricAlgorithm;
|
|
pxCtx->xHashAlgorithm = xHashAlgorithm;
|
|
|
|
/*
|
|
* Initialize the requested hash type
|
|
*/
|
|
if( cryptoHASH_ALGORITHM_SHA1 == pxCtx->xHashAlgorithm )
|
|
{
|
|
mbedtls_sha1_init( &pxCtx->xSHA1Context );
|
|
mbedtls_sha1_starts( &pxCtx->xSHA1Context );
|
|
}
|
|
else
|
|
{
|
|
mbedtls_sha256_init( &pxCtx->xSHA256Context );
|
|
mbedtls_sha256_starts( &pxCtx->xSHA256Context, 0 );
|
|
}
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
/**
|
|
* @brief Adds bytes to an in-progress hash for subsequent signature
|
|
* verification.
|
|
*/
|
|
void CRYPTO_SignatureVerificationUpdate( void * pvContext,
|
|
uint8_t * pucData,
|
|
size_t xDataLength )
|
|
{
|
|
SignatureVerificationStatePtr_t pxCtx = ( SignatureVerificationStatePtr_t ) pvContext; /*lint !e9087 Allow casting void* to other types. */
|
|
|
|
/*
|
|
* Add the data to the hash of the requested type
|
|
*/
|
|
if( cryptoHASH_ALGORITHM_SHA1 == pxCtx->xHashAlgorithm )
|
|
{
|
|
mbedtls_sha1_update( &pxCtx->xSHA1Context, pucData, xDataLength );
|
|
}
|
|
else
|
|
{
|
|
mbedtls_sha256_update( &pxCtx->xSHA256Context, pucData, xDataLength );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Performs signature verification on a cryptographic hash.
|
|
*/
|
|
BaseType_t CRYPTO_SignatureVerificationFinal( void * pvContext,
|
|
char * pcSignerCertificate,
|
|
size_t xSignerCertificateLength,
|
|
uint8_t * pucSignature,
|
|
size_t xSignatureLength )
|
|
{
|
|
BaseType_t xResult = pdTRUE;
|
|
SignatureVerificationStatePtr_t pxCtx =
|
|
( SignatureVerificationStatePtr_t ) pvContext; /*lint !e9087 Allow casting void* to other types. */
|
|
uint8_t ucSHA1[ cryptoSHA1_DIGEST_BYTES ];
|
|
uint8_t ucSHA256[ cryptoSHA256_DIGEST_BYTES ];
|
|
uint8_t * pucHash = NULL;
|
|
size_t xHashLength = 0;
|
|
|
|
/*
|
|
* Finish the hash
|
|
*/
|
|
if( cryptoHASH_ALGORITHM_SHA1 == pxCtx->xHashAlgorithm )
|
|
{
|
|
mbedtls_sha1_finish( &pxCtx->xSHA1Context, ucSHA1 );
|
|
pucHash = ucSHA1;
|
|
xHashLength = cryptoSHA1_DIGEST_BYTES;
|
|
}
|
|
else
|
|
{
|
|
mbedtls_sha256_finish( &pxCtx->xSHA256Context, ucSHA256 );
|
|
pucHash = ucSHA256;
|
|
xHashLength = cryptoSHA256_DIGEST_BYTES;
|
|
}
|
|
|
|
/*
|
|
* Verify the signature
|
|
*/
|
|
xResult = prvVerifySignature( pcSignerCertificate,
|
|
xSignerCertificateLength,
|
|
pxCtx->xHashAlgorithm,
|
|
pucHash,
|
|
xHashLength,
|
|
pucSignature,
|
|
xSignatureLength );
|
|
|
|
/*
|
|
* Clean-up
|
|
*/
|
|
vPortFree( pxCtx );
|
|
|
|
return xResult;
|
|
}
|
|
|
|
#endif /* !WOLF_AWSTLS */
|