[NUC472] Fix SHA accelerator errors

1. Fix clone SHA context error. Convert SHA H/W context to SHA S/W context due to just one instance of SHA H/W.
2. Fix partial update error.
pull/2861/head
ccli8 2016-08-31 11:31:14 +08:00
parent f332ef7a8f
commit cf3d6e06d8
10 changed files with 318 additions and 242 deletions

View File

@ -25,29 +25,19 @@
#include "sha1_alt.h"
#include "crypto-misc.h"
#include "nu_bitutil.h"
#include "string.h"
void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
{
if (crypto_sha_acquire()) {
ctx->mbedtls_sha1_init = mbedtls_sha1_hw_init;
ctx->mbedtls_sha1_free = mbedtls_sha1_hw_free;
ctx->mbedtls_sha1_clone = mbedtls_sha1_hw_clone;
ctx->mbedtls_sha1_starts = mbedtls_sha1_hw_starts;
ctx->mbedtls_sha1_update = mbedtls_sha1_hw_update;
ctx->mbedtls_sha1_finish = mbedtls_sha1_hw_finish;
ctx->mbedtls_sha1_process = mbedtls_sha1_hw_process;
ctx->ishw = 1;
mbedtls_sha1_hw_init(&ctx->hw_ctx);
}
else {
ctx->mbedtls_sha1_init = mbedtls_sha1_sw_init;
ctx->mbedtls_sha1_free = mbedtls_sha1_sw_free;
ctx->mbedtls_sha1_clone = mbedtls_sha1_sw_clone;
ctx->mbedtls_sha1_starts = mbedtls_sha1_sw_starts;
ctx->mbedtls_sha1_update = mbedtls_sha1_sw_update;
ctx->mbedtls_sha1_finish = mbedtls_sha1_sw_finish;
ctx->mbedtls_sha1_process = mbedtls_sha1_sw_process;
ctx->ishw = 0;
mbedtls_sha1_sw_init(&ctx->sw_ctx);
}
ctx->mbedtls_sha1_init(ctx);
}
void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
@ -56,17 +46,41 @@ void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
return;
}
ctx->mbedtls_sha1_free(ctx);
if (ctx->mbedtls_sha1_init == mbedtls_sha1_hw_init) {
if (ctx->ishw) {
mbedtls_sha1_hw_free(&ctx->hw_ctx);
crypto_sha_release();
}
else {
mbedtls_sha1_sw_free(&ctx->sw_ctx);
}
}
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src)
{
*dst = *src;
if (src->ishw) {
// Clone S/W ctx from H/W ctx
dst->ishw = 0;
dst->sw_ctx.total[0] = src->hw_ctx.total;
dst->sw_ctx.total[1] = 0;
{
unsigned char output[20];
crypto_sha_getinternstate(output, sizeof (output));
dst->sw_ctx.state[0] = nu_get32_be(output);
dst->sw_ctx.state[1] = nu_get32_be(output + 4);
dst->sw_ctx.state[2] = nu_get32_be(output + 8);
dst->sw_ctx.state[3] = nu_get32_be(output + 12);
dst->sw_ctx.state[4] = nu_get32_be(output + 16);
}
memcpy(dst->sw_ctx.buffer, src->hw_ctx.buffer, src->hw_ctx.buffer_left);
if (src->hw_ctx.buffer_left == src->hw_ctx.blocksize) {
mbedtls_sha1_sw_process(&dst->sw_ctx, dst->sw_ctx.buffer);
}
}
else {
// Clone S/W ctx from S/W ctx
dst->sw_ctx = src->sw_ctx;
}
}
/*
@ -74,9 +88,12 @@ void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
*/
void mbedtls_sha1_starts(mbedtls_sha1_context *ctx)
{
ctx->mbedtls_sha1_starts(ctx);
return;
if (ctx->ishw) {
mbedtls_sha1_hw_starts(&ctx->hw_ctx);
}
else {
mbedtls_sha1_sw_starts(&ctx->sw_ctx);
}
}
/*
@ -84,7 +101,12 @@ void mbedtls_sha1_starts(mbedtls_sha1_context *ctx)
*/
void mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
{
ctx->mbedtls_sha1_update(ctx, input, ilen);
if (ctx->ishw) {
mbedtls_sha1_hw_update(&ctx->hw_ctx, input, ilen);
}
else {
mbedtls_sha1_sw_update(&ctx->sw_ctx, input, ilen);
}
}
/*
@ -92,12 +114,22 @@ void mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input,
*/
void mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20])
{
ctx->mbedtls_sha1_finish(ctx, output);
if (ctx->ishw) {
mbedtls_sha1_hw_finish(&ctx->hw_ctx, output);
}
else {
mbedtls_sha1_sw_finish(&ctx->sw_ctx, output);
}
}
void mbedtls_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
{
ctx->mbedtls_sha1_process(ctx, data);
if (ctx->ishw) {
mbedtls_sha1_hw_process(&ctx->hw_ctx, data);
}
else {
mbedtls_sha1_sw_process(&ctx->sw_ctx, data);
}
}
#endif /* MBEDTLS_SHA1_ALT */

View File

@ -40,18 +40,9 @@ struct mbedtls_sha1_context_s;
*/
typedef struct mbedtls_sha1_context_s
{
union {
crypto_sha_context hw_ctx;
mbedtls_sha1_sw_context sw_ctx;
};
void (*mbedtls_sha1_init)(struct mbedtls_sha1_context_s *ctx);
void (*mbedtls_sha1_free)(struct mbedtls_sha1_context_s *ctx);
void (*mbedtls_sha1_clone)(struct mbedtls_sha1_context_s *dst, const struct mbedtls_sha1_context_s *src);
void (*mbedtls_sha1_starts)(struct mbedtls_sha1_context_s *ctx);
void (*mbedtls_sha1_update)(struct mbedtls_sha1_context_s *ctx, const unsigned char *input, size_t ilen);
void (*mbedtls_sha1_finish)(struct mbedtls_sha1_context_s *ctx, unsigned char output[20]);
void (*mbedtls_sha1_process)(struct mbedtls_sha1_context_s *ctx, const unsigned char data[64]);
int ishw;
crypto_sha_context hw_ctx;
mbedtls_sha1_sw_context sw_ctx;
}
mbedtls_sha1_context;

View File

@ -65,32 +65,30 @@ static void mbedtls_zeroize( void *v, size_t n ) {
}
#endif
void mbedtls_sha1_sw_init( mbedtls_sha1_context *ctx )
void mbedtls_sha1_sw_init( mbedtls_sha1_sw_context *ctx )
{
memset( &ctx->sw_ctx, 0, sizeof( ctx->sw_ctx ) );
memset( ctx, 0, sizeof( mbedtls_sha1_sw_context ) );
}
void mbedtls_sha1_sw_free( mbedtls_sha1_context *ctx )
void mbedtls_sha1_sw_free( mbedtls_sha1_sw_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( &ctx->sw_ctx, sizeof( ctx->sw_ctx ) );
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_sw_context ) );
}
void mbedtls_sha1_sw_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src )
void mbedtls_sha1_sw_clone( mbedtls_sha1_sw_context *dst,
const mbedtls_sha1_sw_context *src )
{
dst->sw_ctx = src->sw_ctx;
*dst = *src;
}
/*
* SHA-1 context setup
*/
void mbedtls_sha1_sw_starts( mbedtls_sha1_context *ctx_ )
void mbedtls_sha1_sw_starts( mbedtls_sha1_sw_context *ctx )
{
mbedtls_sha1_sw_context *ctx = &ctx_->sw_ctx;
ctx->total[0] = 0;
ctx->total[1] = 0;
@ -101,10 +99,8 @@ void mbedtls_sha1_sw_starts( mbedtls_sha1_context *ctx_ )
ctx->state[4] = 0xC3D2E1F0;
}
void mbedtls_sha1_sw_process( mbedtls_sha1_context *ctx_, const unsigned char data[64] )
void mbedtls_sha1_sw_process( mbedtls_sha1_sw_context *ctx, const unsigned char data[64] )
{
mbedtls_sha1_sw_context *ctx = &ctx_->sw_ctx;
uint32_t temp, W[16], A, B, C, D, E;
GET_UINT32_BE( W[ 0], data, 0 );
@ -262,10 +258,8 @@ void mbedtls_sha1_sw_process( mbedtls_sha1_context *ctx_, const unsigned char da
/*
* SHA-1 process buffer
*/
void mbedtls_sha1_sw_update( mbedtls_sha1_context *ctx_, const unsigned char *input, size_t ilen )
void mbedtls_sha1_sw_update( mbedtls_sha1_sw_context *ctx, const unsigned char *input, size_t ilen )
{
mbedtls_sha1_sw_context *ctx = &ctx_->sw_ctx;
size_t fill;
uint32_t left;
@ -284,7 +278,7 @@ void mbedtls_sha1_sw_update( mbedtls_sha1_context *ctx_, const unsigned char *in
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha1_sw_process( ctx_, ctx->buffer );
mbedtls_sha1_sw_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
@ -292,7 +286,7 @@ void mbedtls_sha1_sw_update( mbedtls_sha1_context *ctx_, const unsigned char *in
while( ilen >= 64 )
{
mbedtls_sha1_sw_process( ctx_, input );
mbedtls_sha1_sw_process( ctx, input );
input += 64;
ilen -= 64;
}
@ -312,10 +306,8 @@ static const unsigned char sha1_padding[64] =
/*
* SHA-1 final digest
*/
void mbedtls_sha1_sw_finish( mbedtls_sha1_context *ctx_, unsigned char output[20] )
void mbedtls_sha1_sw_finish( mbedtls_sha1_sw_context *ctx, unsigned char output[20] )
{
mbedtls_sha1_sw_context *ctx = &ctx_->sw_ctx;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
@ -330,8 +322,8 @@ void mbedtls_sha1_sw_finish( mbedtls_sha1_context *ctx_, unsigned char output[20
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha1_sw_update( ctx_, sha1_padding, padn );
mbedtls_sha1_sw_update( ctx_, msglen, 8 );
mbedtls_sha1_sw_update( ctx, sha1_padding, padn );
mbedtls_sha1_sw_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );

View File

@ -39,8 +39,6 @@
extern "C" {
#endif
struct mbedtls_sha1_context_s;
/**
* \brief SHA-1 context structure
*/
@ -57,14 +55,14 @@ mbedtls_sha1_sw_context;
*
* \param ctx SHA-1 context to be initialized
*/
void mbedtls_sha1_sw_init( struct mbedtls_sha1_context_s *ctx );
void mbedtls_sha1_sw_init( mbedtls_sha1_sw_context *ctx );
/**
* \brief Clear SHA-1 context
*
* \param ctx SHA-1 context to be cleared
*/
void mbedtls_sha1_sw_free( struct mbedtls_sha1_context_s *ctx );
void mbedtls_sha1_sw_free( mbedtls_sha1_sw_context *ctx );
/**
* \brief Clone (the state of) a SHA-1 context
@ -72,15 +70,15 @@ void mbedtls_sha1_sw_free( struct mbedtls_sha1_context_s *ctx );
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha1_sw_clone( struct mbedtls_sha1_context_s *dst,
const struct mbedtls_sha1_context_s *src );
void mbedtls_sha1_sw_clone( mbedtls_sha1_sw_context *dst,
const mbedtls_sha1_sw_context *src );
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_sha1_sw_starts( struct mbedtls_sha1_context_s *ctx );
void mbedtls_sha1_sw_starts( mbedtls_sha1_sw_context *ctx );
/**
* \brief SHA-1 process buffer
@ -89,7 +87,7 @@ void mbedtls_sha1_sw_starts( struct mbedtls_sha1_context_s *ctx );
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha1_sw_update( struct mbedtls_sha1_context_s *ctx, const unsigned char *input, size_t ilen );
void mbedtls_sha1_sw_update( mbedtls_sha1_sw_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief SHA-1 final digest
@ -97,10 +95,10 @@ void mbedtls_sha1_sw_update( struct mbedtls_sha1_context_s *ctx, const unsigned
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void mbedtls_sha1_sw_finish( struct mbedtls_sha1_context_s *ctx, unsigned char output[20] );
void mbedtls_sha1_sw_finish( mbedtls_sha1_sw_context *ctx, unsigned char output[20] );
/* Internal use */
void mbedtls_sha1_sw_process( struct mbedtls_sha1_context_s *ctx, const unsigned char data[64] );
void mbedtls_sha1_sw_process( mbedtls_sha1_sw_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}

View File

@ -25,29 +25,19 @@
#include "sha256_alt.h"
#include "crypto-misc.h"
#include "nu_bitutil.h"
#include "string.h"
void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
{
if (crypto_sha_acquire()) {
ctx->mbedtls_sha256_init = mbedtls_sha256_hw_init;
ctx->mbedtls_sha256_free = mbedtls_sha256_hw_free;
ctx->mbedtls_sha256_clone = mbedtls_sha256_hw_clone;
ctx->mbedtls_sha256_starts = mbedtls_sha256_hw_starts;
ctx->mbedtls_sha256_update = mbedtls_sha256_hw_update;
ctx->mbedtls_sha256_finish = mbedtls_sha256_hw_finish;
ctx->mbedtls_sha256_process = mbedtls_sha256_hw_process;
ctx->ishw = 1;
mbedtls_sha256_hw_init(&ctx->hw_ctx);
}
else {
ctx->mbedtls_sha256_init = mbedtls_sha256_sw_init;
ctx->mbedtls_sha256_free = mbedtls_sha256_sw_free;
ctx->mbedtls_sha256_clone = mbedtls_sha256_sw_clone;
ctx->mbedtls_sha256_starts = mbedtls_sha256_sw_starts;
ctx->mbedtls_sha256_update = mbedtls_sha256_sw_update;
ctx->mbedtls_sha256_finish = mbedtls_sha256_sw_finish;
ctx->mbedtls_sha256_process = mbedtls_sha256_sw_process;
ctx->ishw = 0;
mbedtls_sha256_sw_init(&ctx->sw_ctx);
}
ctx->mbedtls_sha256_init(ctx);
}
void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
@ -56,17 +46,45 @@ void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
return;
}
ctx->mbedtls_sha256_free(ctx);
if (ctx->mbedtls_sha256_init == mbedtls_sha256_hw_init) {
if (ctx->ishw) {
mbedtls_sha256_hw_free(&ctx->hw_ctx);
crypto_sha_release();
}
else {
mbedtls_sha256_sw_free(&ctx->sw_ctx);
}
}
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src)
{
*dst = *src;
if (src->ishw) {
// Clone S/W ctx from H/W ctx
dst->ishw = 0;
dst->sw_ctx.total[0] = src->hw_ctx.total;
dst->sw_ctx.total[1] = 0;
{
unsigned char output[32];
crypto_sha_getinternstate(output, sizeof (output));
dst->sw_ctx.state[0] = nu_get32_be(output);
dst->sw_ctx.state[1] = nu_get32_be(output + 4);
dst->sw_ctx.state[2] = nu_get32_be(output + 8);
dst->sw_ctx.state[3] = nu_get32_be(output + 12);
dst->sw_ctx.state[4] = nu_get32_be(output + 16);
dst->sw_ctx.state[5] = nu_get32_be(output + 20);
dst->sw_ctx.state[6] = nu_get32_be(output + 24);
dst->sw_ctx.state[7] = nu_get32_be(output + 28);
}
memcpy(dst->sw_ctx.buffer, src->hw_ctx.buffer, src->hw_ctx.buffer_left);
dst->sw_ctx.is224 = src->hw_ctx.is224;
if (src->hw_ctx.buffer_left == src->hw_ctx.blocksize) {
mbedtls_sha256_sw_process(&dst->sw_ctx, dst->sw_ctx.buffer);
}
}
else {
// Clone S/W ctx from S/W ctx
dst->sw_ctx = src->sw_ctx;
}
}
/*
@ -74,9 +92,12 @@ void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
*/
void mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
{
ctx->mbedtls_sha256_starts(ctx, is224);
return;
if (ctx->ishw) {
mbedtls_sha256_hw_starts(&ctx->hw_ctx, is224);
}
else {
mbedtls_sha256_sw_starts(&ctx->sw_ctx, is224);
}
}
/*
@ -84,20 +105,35 @@ void mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
*/
void mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
{
ctx->mbedtls_sha256_update(ctx, input, ilen);
if (ctx->ishw) {
mbedtls_sha256_hw_update(&ctx->hw_ctx, input, ilen);
}
else {
mbedtls_sha256_sw_update(&ctx->sw_ctx, input, ilen);
}
}
/*
* SHA-256 final digest
*/
void mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char output[20])
void mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char output[32])
{
ctx->mbedtls_sha256_finish(ctx, output);
if (ctx->ishw) {
mbedtls_sha256_hw_finish(&ctx->hw_ctx, output);
}
else {
mbedtls_sha256_sw_finish(&ctx->sw_ctx, output);
}
}
void mbedtls_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
{
ctx->mbedtls_sha256_process(ctx, data);
if (ctx->ishw) {
mbedtls_sha256_hw_process(&ctx->hw_ctx, data);
}
else {
mbedtls_sha256_sw_process(&ctx->sw_ctx, data);
}
}
#endif /* MBEDTLS_SHA256_ALT */

View File

@ -40,18 +40,9 @@ struct mbedtls_sha256_context_s;
*/
typedef struct mbedtls_sha256_context_s
{
union {
crypto_sha_context hw_ctx;
mbedtls_sha256_sw_context sw_ctx;
};
void (*mbedtls_sha256_init)(struct mbedtls_sha256_context_s *ctx);
void (*mbedtls_sha256_free)(struct mbedtls_sha256_context_s *ctx);
void (*mbedtls_sha256_clone)(struct mbedtls_sha256_context_s *dst, const struct mbedtls_sha256_context_s *src);
void (*mbedtls_sha256_starts)(struct mbedtls_sha256_context_s *ctx, int is224);
void (*mbedtls_sha256_update)(struct mbedtls_sha256_context_s *ctx, const unsigned char *input, size_t ilen);
void (*mbedtls_sha256_finish)(struct mbedtls_sha256_context_s *ctx, unsigned char output[20]);
void (*mbedtls_sha256_process)(struct mbedtls_sha256_context_s *ctx, const unsigned char data[64]);
int ishw;
crypto_sha_context hw_ctx;
mbedtls_sha256_sw_context sw_ctx;
}
mbedtls_sha256_context;

View File

@ -65,32 +65,30 @@ do { \
} while( 0 )
#endif
void mbedtls_sha256_sw_init( mbedtls_sha256_context *ctx )
void mbedtls_sha256_sw_init( mbedtls_sha256_sw_context *ctx )
{
memset( &ctx->sw_ctx, 0, sizeof( ctx->sw_ctx ) );
memset( ctx, 0, sizeof( mbedtls_sha256_sw_context ) );
}
void mbedtls_sha256_sw_free( mbedtls_sha256_context *ctx )
void mbedtls_sha256_sw_free( mbedtls_sha256_sw_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( &ctx->sw_ctx, sizeof( ctx->sw_ctx ) );
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_sw_context ) );
}
void mbedtls_sha256_sw_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src )
void mbedtls_sha256_sw_clone( mbedtls_sha256_sw_context *dst,
const mbedtls_sha256_sw_context *src )
{
dst->sw_ctx = src->sw_ctx;
*dst = *src;
}
/*
* SHA-256 context setup
*/
void mbedtls_sha256_sw_starts( mbedtls_sha256_context *ctx_, int is224 )
void mbedtls_sha256_sw_starts( mbedtls_sha256_sw_context *ctx, int is224 )
{
mbedtls_sha256_sw_context *ctx = &ctx_->sw_ctx;
ctx->total[0] = 0;
ctx->total[1] = 0;
@ -167,10 +165,8 @@ static const uint32_t K[] =
d += temp1; h = temp1 + temp2; \
}
void mbedtls_sha256_sw_process( mbedtls_sha256_context *ctx_, const unsigned char data[64] )
void mbedtls_sha256_sw_process( mbedtls_sha256_sw_context *ctx, const unsigned char data[64] )
{
mbedtls_sha256_sw_context *ctx = &ctx_->sw_ctx;
uint32_t temp1, temp2, W[64];
uint32_t A[8];
unsigned int i;
@ -227,11 +223,9 @@ void mbedtls_sha256_sw_process( mbedtls_sha256_context *ctx_, const unsigned cha
/*
* SHA-256 process buffer
*/
void mbedtls_sha256_sw_update( mbedtls_sha256_context *ctx_, const unsigned char *input,
void mbedtls_sha256_sw_update( mbedtls_sha256_sw_context *ctx, const unsigned char *input,
size_t ilen )
{
mbedtls_sha256_sw_context *ctx = &ctx_->sw_ctx;
size_t fill;
uint32_t left;
@ -250,7 +244,7 @@ void mbedtls_sha256_sw_update( mbedtls_sha256_context *ctx_, const unsigned char
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha256_sw_process( ctx_, ctx->buffer );
mbedtls_sha256_sw_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
@ -258,7 +252,7 @@ void mbedtls_sha256_sw_update( mbedtls_sha256_context *ctx_, const unsigned char
while( ilen >= 64 )
{
mbedtls_sha256_sw_process( ctx_, input );
mbedtls_sha256_sw_process( ctx, input );
input += 64;
ilen -= 64;
}
@ -278,10 +272,8 @@ static const unsigned char sha256_padding[64] =
/*
* SHA-256 final digest
*/
void mbedtls_sha256_sw_finish( mbedtls_sha256_context *ctx_, unsigned char output[32] )
void mbedtls_sha256_sw_finish( mbedtls_sha256_sw_context *ctx, unsigned char output[32] )
{
mbedtls_sha256_sw_context *ctx = &ctx_->sw_ctx;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
@ -296,8 +288,8 @@ void mbedtls_sha256_sw_finish( mbedtls_sha256_context *ctx_, unsigned char outpu
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha256_sw_update( ctx_, sha256_padding, padn );
mbedtls_sha256_sw_update( ctx_, msglen, 8 );
mbedtls_sha256_sw_update( ctx, sha256_padding, padn );
mbedtls_sha256_sw_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );

View File

@ -39,8 +39,6 @@
extern "C" {
#endif
struct mbedtls_sha256_context_s;
/**
* \brief SHA-256 context structure
*/
@ -58,14 +56,14 @@ mbedtls_sha256_sw_context;
*
* \param ctx SHA-256 context to be initialized
*/
void mbedtls_sha256_sw_init( struct mbedtls_sha256_context_s *ctx );
void mbedtls_sha256_sw_init( mbedtls_sha256_sw_context *ctx );
/**
* \brief Clear SHA-256 context
*
* \param ctx SHA-256 context to be cleared
*/
void mbedtls_sha256_sw_free( struct mbedtls_sha256_context_s *ctx );
void mbedtls_sha256_sw_free( mbedtls_sha256_sw_context *ctx );
/**
* \brief Clone (the state of) a SHA-256 context
@ -73,8 +71,8 @@ void mbedtls_sha256_sw_free( struct mbedtls_sha256_context_s *ctx );
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha256_sw_clone( struct mbedtls_sha256_context_s *dst,
const struct mbedtls_sha256_context_s *src );
void mbedtls_sha256_sw_clone( mbedtls_sha256_sw_context *dst,
const mbedtls_sha256_sw_context *src );
/**
* \brief SHA-256 context setup
@ -82,7 +80,7 @@ void mbedtls_sha256_sw_clone( struct mbedtls_sha256_context_s *dst,
* \param ctx context to be initialized
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void mbedtls_sha256_sw_starts( struct mbedtls_sha256_context_s *ctx, int is224 );
void mbedtls_sha256_sw_starts( mbedtls_sha256_sw_context *ctx, int is224 );
/**
* \brief SHA-256 process buffer
@ -91,7 +89,7 @@ void mbedtls_sha256_sw_starts( struct mbedtls_sha256_context_s *ctx, int is224 )
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha256_sw_update( struct mbedtls_sha256_context_s *ctx, const unsigned char *input,
void mbedtls_sha256_sw_update( mbedtls_sha256_sw_context *ctx, const unsigned char *input,
size_t ilen );
/**
@ -100,10 +98,10 @@ void mbedtls_sha256_sw_update( struct mbedtls_sha256_context_s *ctx, const unsig
* \param ctx SHA-256 context
* \param output SHA-224/256 checksum result
*/
void mbedtls_sha256_sw_finish( struct mbedtls_sha256_context_s *ctx, unsigned char output[32] );
void mbedtls_sha256_sw_finish( mbedtls_sha256_sw_context *ctx, unsigned char output[32] );
/* Internal use */
void mbedtls_sha256_sw_process( struct mbedtls_sha256_context_s *ctx, const unsigned char data[64] );
void mbedtls_sha256_sw_process( mbedtls_sha256_sw_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}

View File

@ -42,59 +42,79 @@
#include <string.h>
static void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen);
static void crypto_sha_getinternstate(unsigned char output[], size_t olen);
static void crypto_sha_lastword(crypto_sha_context *ctx, int islast);
void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen);
void crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int islast);
void crypto_sha_getinternstate(unsigned char output[], size_t olen);
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#if defined(MBEDTLS_SHA1_ALT)
void mbedtls_sha1_hw_init(mbedtls_sha1_context *ctx)
void mbedtls_sha1_hw_init(crypto_sha_context *ctx)
{
crypto_init();
memset(&ctx->hw_ctx, 0, sizeof(ctx->hw_ctx));
memset(ctx, 0, sizeof(crypto_sha_context));
}
void mbedtls_sha1_hw_free(mbedtls_sha1_context *ctx)
void mbedtls_sha1_hw_free(crypto_sha_context *ctx)
{
if (ctx == NULL) {
return;
}
crypto_zeroize(&ctx->hw_ctx, sizeof(ctx->hw_ctx));
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
void mbedtls_sha1_hw_clone(mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src)
void mbedtls_sha1_hw_clone(crypto_sha_context *dst,
const crypto_sha_context *src)
{
dst->hw_ctx = src->hw_ctx;
*dst = *src;
}
void mbedtls_sha1_hw_starts(mbedtls_sha1_context *ctx)
void mbedtls_sha1_hw_starts(crypto_sha_context *ctx)
{
ctx->hw_ctx.total = 0;
ctx->hw_ctx.lastword_size = 0;
ctx->hw_ctx.blocksize = 64;
ctx->hw_ctx.blocksize_mask = 0x3F;
// NOTE: mbedtls may call mbedtls_shaXXX_starts multiple times and then call the ending mbedtls_shaXXX_finish. Guard from it.
CRPT->SHA_CTL |= CRPT_SHA_CTL_STOP_Msk;
ctx->total = 0;
ctx->buffer_left = 0;
ctx->blocksize = 64;
ctx->blocksize_mask = 0x3F;
SHA_Open(SHA_MODE_SHA1, SHA_NO_SWAP);
// Ensure we have correct initial inernal states in SHA_DGST registers even though SHA H/W is not actually started.
CRPT->SHA_CTL |= CRPT_SHA_CTL_START_Msk;
return;
}
void mbedtls_sha1_hw_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
void mbedtls_sha1_hw_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
{
crypto_sha_update(&ctx->hw_ctx, input, ilen);
crypto_sha_update(ctx, input, ilen);
}
void mbedtls_sha1_hw_finish(mbedtls_sha1_context *ctx, unsigned char output[20])
void mbedtls_sha1_hw_finish(crypto_sha_context *ctx, unsigned char output[20])
{
crypto_sha_lastword(&ctx->hw_ctx, 1);
crypto_sha_getinternstate(output, 20);
// H/W SHA cannot handle zero data well. Fall back to S/W SHA.
if (ctx->total) {
crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, 1);
ctx->buffer_left = 0;
crypto_sha_getinternstate(output, 20);
CRPT->SHA_CTL |= CRPT_SHA_CTL_STOP_Msk;
}
else {
mbedtls_sha1_sw_context ctx_sw;
mbedtls_sha1_sw_init(&ctx_sw);
mbedtls_sha1_sw_starts(&ctx_sw);
mbedtls_sha1_sw_finish(&ctx_sw, output);
mbedtls_sha1_sw_free(&ctx_sw);
}
}
void mbedtls_sha1_hw_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
void mbedtls_sha1_hw_process(crypto_sha_context *ctx, const unsigned char data[64])
{
mbedtls_sha1_hw_update(ctx, data, 64);
}
@ -103,52 +123,72 @@ void mbedtls_sha1_hw_process(mbedtls_sha1_context *ctx, const unsigned char data
#if defined(MBEDTLS_SHA256_ALT)
void mbedtls_sha256_hw_init(mbedtls_sha256_context *ctx)
void mbedtls_sha256_hw_init(crypto_sha_context *ctx)
{
crypto_init();
memset(&ctx->hw_ctx, 0, sizeof(ctx->hw_ctx));
memset(ctx, 0, sizeof(crypto_sha_context));
}
void mbedtls_sha256_hw_free(mbedtls_sha256_context *ctx)
void mbedtls_sha256_hw_free(crypto_sha_context *ctx)
{
if (ctx == NULL) {
return;
}
crypto_zeroize(&ctx->hw_ctx, sizeof(ctx->hw_ctx));
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
void mbedtls_sha256_hw_clone(mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src)
void mbedtls_sha256_hw_clone(crypto_sha_context *dst,
const crypto_sha_context *src)
{
dst->hw_ctx = src->hw_ctx;
*dst = *src;
}
void mbedtls_sha256_hw_starts( mbedtls_sha256_context *ctx, int is224)
void mbedtls_sha256_hw_starts( crypto_sha_context *ctx, int is224)
{
ctx->hw_ctx.total = 0;
ctx->hw_ctx.lastword_size = 0;
ctx->hw_ctx.blocksize = 64;
ctx->hw_ctx.blocksize_mask = 0x3F;
ctx->hw_ctx.is224 = is224;
// NOTE: mbedtls may call mbedtls_shaXXX_starts multiple times and then call the ending mbedtls_shaXXX_finish. Guard from it.
CRPT->SHA_CTL |= CRPT_SHA_CTL_STOP_Msk;
ctx->total = 0;
ctx->buffer_left = 0;
ctx->blocksize = 64;
ctx->blocksize_mask = 0x3F;
ctx->is224 = is224;
SHA_Open(is224 ? SHA_MODE_SHA224 : SHA_MODE_SHA256, SHA_NO_SWAP);
// Ensure we have correct initial inernal states in SHA_DGST registers even though SHA H/W is not actually started.
CRPT->SHA_CTL |= CRPT_SHA_CTL_START_Msk;
return;
}
void mbedtls_sha256_hw_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
void mbedtls_sha256_hw_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
{
crypto_sha_update(&ctx->hw_ctx, input, ilen);
crypto_sha_update(ctx, input, ilen);
}
void mbedtls_sha256_hw_finish(mbedtls_sha256_context *ctx, unsigned char output[32])
void mbedtls_sha256_hw_finish(crypto_sha_context *ctx, unsigned char output[32])
{
crypto_sha_lastword(&ctx->hw_ctx, 1);
crypto_sha_getinternstate(output, ctx->hw_ctx.is224 ? 28 : 32);
// H/W SHA cannot handle zero data well. Fall back to S/W SHA.
if (ctx->total) {
crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, 1);
ctx->buffer_left = 0;
crypto_sha_getinternstate(output, ctx->is224 ? 28 : 32);
CRPT->SHA_CTL |= CRPT_SHA_CTL_STOP_Msk;
}
else {
mbedtls_sha256_sw_context ctx_sw;
mbedtls_sha256_sw_init(&ctx_sw);
mbedtls_sha256_sw_starts(&ctx_sw, ctx->is224);
mbedtls_sha256_sw_finish(&ctx_sw, output);
mbedtls_sha256_sw_free(&ctx_sw);
}
}
void mbedtls_sha256_hw_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
void mbedtls_sha256_hw_process(crypto_sha_context *ctx, const unsigned char data[64])
{
mbedtls_sha256_hw_update(ctx, data, 64);
}
@ -163,18 +203,54 @@ void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size
return;
}
crypto_sha_lastword(ctx, 0);
size_t fill = ctx->blocksize - ctx->buffer_left;
ctx->total += (uint32_t) ilen;
const unsigned char *in_pos = input;
uint32_t rmn = ilen;
if (ctx->buffer_left && ilen >= fill) {
memcpy((void *) (ctx->buffer + ctx->buffer_left), input, fill);
input += fill;
ilen -= fill;
ctx->buffer_left += fill;
if (ilen) {
crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, 0);
ctx->buffer_left = 0;
}
}
while (ilen > ctx->blocksize) {
crypto_sha_update_nobuf(ctx, input, ctx->blocksize, 0);
input += ctx->blocksize;
ilen -= ctx->blocksize;
}
if (ilen > 0) {
memcpy((void *) (ctx->buffer + ctx->buffer_left), input, ilen);
ctx->buffer_left += ilen;
}
}
void crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int islast)
{
unsigned char *in_pos = input;
int rmn = ilen;
uint32_t sha_ctl_start = (CRPT->SHA_CTL & ~(CRPT_SHA_CTL_DMALAST_Msk | CRPT_SHA_CTL_DMAEN_Msk)) | CRPT_SHA_CTL_START_Msk;
while (rmn > 4) {
while (rmn > 0) {
CRPT->SHA_CTL = sha_ctl_start;
uint32_t data = nu_get32_be(in_pos);
if (islast && rmn <= 4) {
uint32_t lastblock_size = ctx->total & ctx->blocksize_mask;
if (lastblock_size == 0) {
lastblock_size = ctx->blocksize;
}
CRPT->SHA_DMACNT = lastblock_size;
CRPT->SHA_CTL = sha_ctl_start | CRPT_SHA_CTL_DMALAST_Msk;
}
else {
CRPT->SHA_CTL = sha_ctl_start;
}
while (! (CRPT->SHA_STS & CRPT_SHA_STS_DATINREQ_Msk));
CRPT->SHA_DATIN = data;
@ -182,12 +258,9 @@ void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size
rmn -= 4;
}
MBED_ASSERT(rmn > 0 && rmn <= 4);
unsigned char lastword_buf[4];
memcpy(lastword_buf, in_pos, rmn);
memset(lastword_buf + rmn, 0x00, 4 - rmn);
ctx->lastword = nu_get32_be(lastword_buf);
ctx->lastword_size = rmn;
if (islast) {
while (CRPT->SHA_STS & CRPT_SHA_STS_BUSY_Msk);
}
}
void crypto_sha_getinternstate(unsigned char output[], size_t olen)
@ -204,33 +277,6 @@ void crypto_sha_getinternstate(unsigned char output[], size_t olen)
}
}
void crypto_sha_lastword(crypto_sha_context *ctx, int islast)
{
uint32_t sha_ctl_start = (CRPT->SHA_CTL & ~(CRPT_SHA_CTL_DMALAST_Msk | CRPT_SHA_CTL_DMAEN_Msk)) | CRPT_SHA_CTL_START_Msk;
if (ctx->lastword_size) {
if (islast) {
uint32_t lastblock_size = ctx->total & ctx->blocksize_mask;
if (lastblock_size == 0) {
lastblock_size = ctx->blocksize;
}
CRPT->SHA_DMACNT = lastblock_size;
CRPT->SHA_CTL = sha_ctl_start | CRPT_SHA_CTL_DMALAST_Msk;
}
else {
CRPT->SHA_CTL = sha_ctl_start;
}
while (! (CRPT->SHA_STS & CRPT_SHA_STS_DATINREQ_Msk));
CRPT->SHA_DATIN = ctx->lastword;
if (islast) {
while (CRPT->SHA_STS & CRPT_SHA_STS_BUSY_Msk);
}
ctx->lastword_size = 0;
}
}
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */

View File

@ -37,8 +37,8 @@ extern "C" {
typedef struct
{
uint32_t total; /*!< number of bytes processed */
uint32_t lastword; /*!< last word unprocessed */
uint16_t lastword_size; /*!< number of bytes of last word unprocessed */
unsigned char buffer[128]; /*!< data block being processed. Max of SHA-1/SHA-256/SHA-512 */
uint16_t buffer_left;
uint16_t blocksize; /*!< block size */
uint32_t blocksize_mask; /*!< block size mask */
@ -46,34 +46,34 @@ typedef struct
}
crypto_sha_context;
void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen);
void crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int islast);
void crypto_sha_getinternstate(unsigned char output[], size_t olen);
#if defined(MBEDTLS_SHA1_ALT)
struct mbedtls_sha1_context_s;
void mbedtls_sha1_hw_init( struct mbedtls_sha1_context_s *ctx );
void mbedtls_sha1_hw_free( struct mbedtls_sha1_context_s *ctx );
void mbedtls_sha1_hw_clone( struct mbedtls_sha1_context_s *dst,
const struct mbedtls_sha1_context_s *src );
void mbedtls_sha1_hw_starts( struct mbedtls_sha1_context_s *ctx );
void mbedtls_sha1_hw_update( struct mbedtls_sha1_context_s *ctx, const unsigned char *input, size_t ilen );
void mbedtls_sha1_hw_finish( struct mbedtls_sha1_context_s *ctx, unsigned char output[20] );
void mbedtls_sha1_hw_process( struct mbedtls_sha1_context_s *ctx, const unsigned char data[64] );
void mbedtls_sha1_hw_init( crypto_sha_context *ctx );
void mbedtls_sha1_hw_free( crypto_sha_context *ctx );
void mbedtls_sha1_hw_clone( crypto_sha_context *dst,
const crypto_sha_context *src );
void mbedtls_sha1_hw_starts( crypto_sha_context *ctx );
void mbedtls_sha1_hw_update( crypto_sha_context *ctx, const unsigned char *input, size_t ilen );
void mbedtls_sha1_hw_finish( crypto_sha_context *ctx, unsigned char output[20] );
void mbedtls_sha1_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
#endif /* MBEDTLS_SHA1_ALT */
#if defined(MBEDTLS_SHA256_ALT)
struct mbedtls_sha256_context_s;
void mbedtls_sha256_hw_init( struct mbedtls_sha256_context_s *ctx );
void mbedtls_sha256_hw_free( struct mbedtls_sha256_context_s *ctx );
void mbedtls_sha256_hw_clone( struct mbedtls_sha256_context_s *dst,
const struct mbedtls_sha256_context_s *src );
void mbedtls_sha256_hw_starts( struct mbedtls_sha256_context_s *ctx, int is224 );
void mbedtls_sha256_hw_update( struct mbedtls_sha256_context_s *ctx, const unsigned char *input,
void mbedtls_sha256_hw_init( crypto_sha_context *ctx );
void mbedtls_sha256_hw_free( crypto_sha_context *ctx );
void mbedtls_sha256_hw_clone( crypto_sha_context *dst,
const crypto_sha_context *src );
void mbedtls_sha256_hw_starts( crypto_sha_context *ctx, int is224 );
void mbedtls_sha256_hw_update( crypto_sha_context *ctx, const unsigned char *input,
size_t ilen );
void mbedtls_sha256_hw_finish( struct mbedtls_sha256_context_s *ctx, unsigned char output[32] );
void mbedtls_sha256_hw_process( struct mbedtls_sha256_context_s *ctx, const unsigned char data[64] );
void mbedtls_sha256_hw_finish( crypto_sha_context *ctx, unsigned char output[32] );
void mbedtls_sha256_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
#endif /* MBEDTLS_SHA256_ALT */