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

MD5, SHA1 and SHA256 hardware acceleration not working for STM32F439xI #5079

Closed
andresag01 opened this issue Sep 12, 2017 · 12 comments · Fixed by #5630
Closed

MD5, SHA1 and SHA256 hardware acceleration not working for STM32F439xI #5079

andresag01 opened this issue Sep 12, 2017 · 12 comments · Fixed by #5630

Comments

@andresag01
Copy link

Description

This problem seems to be closely related to #4928, which is a failure in AES hardware acceleration for STM32F439xI family of targets only. The cause of the failures seems to be that the hardware acceleration code for these targets cannot correctly handle interleaved operation of multiple mbedtls contexts for the SHA1, MD5 and SHA256 crypto primitives. I have written the following test that exercises the problem:

#include "mbed.h"

#include "mbedtls/aes.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/des.h"
#include "mbedtls/md5.h"

#include "mbedtls/platform.h"
#include "mbedtls/error.h"

#define REPETITIONS 5

#if !defined(MBEDTLS_AES_ALT)
#warning "AES hardware acceleration is not enabled!"
#endif

#if !defined(MBEDTLS_SHA1_ALT)
#warning "SHA1 hardware acceleration is not enabled!"
#endif

#if !defined(MBEDTLS_SHA256_ALT)
#warning "SHA256 hardware acceleration is not enabled!"
#endif

#if !defined(MBEDTLS_MD5_ALT)
#warning "MD5 hardware acceleration is not enabled!"
#endif

/*****************************************************************************/
/*************************AES-CBC tests***************************************/
/*****************************************************************************/

#define AES_CTX_COUNT 12

const unsigned char keys[AES_CTX_COUNT][16] = {
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0xe3, 0x7b, 0x1c, 0x6a, 0xa2, 0x84, 0x6f, 0x6f,
      0xdb, 0x41, 0x3f, 0x23, 0x8b, 0x08, 0x9f, 0x23, },
    { 0x6c, 0x00, 0x2b, 0x68, 0x24, 0x83, 0xe0, 0xca,
      0xbc, 0xc7, 0x31, 0xc2, 0x53, 0xbe, 0x56, 0x74, },
    { 0x14, 0x3a, 0xe8, 0xed, 0x65, 0x55, 0xab, 0xa9,
      0x61, 0x10, 0xab, 0x58, 0x89, 0x3a, 0x8a, 0xe1, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
};

const unsigned char inputs[AES_CTX_COUNT][16] = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
    { 0x6a, 0x11, 0x8a, 0x87, 0x45, 0x19, 0xe6, 0x4e,
      0x99, 0x63, 0x79, 0x8a, 0x50, 0x3f, 0x1d, 0x35, },
    { 0xcb, 0x9f, 0xce, 0xec, 0x81, 0x28, 0x6c, 0xa3,
      0xe9, 0x89, 0xbd, 0x97, 0x9b, 0x0c, 0xb2, 0x84, },
    { 0xb2, 0x6a, 0xeb, 0x18, 0x74, 0xe4, 0x7c, 0xa8,
      0x35, 0x8f, 0xf2, 0x23, 0x78, 0xf0, 0x91, 0x44, },
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, },
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, },
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, },
};

const unsigned char results[AES_CTX_COUNT][16] = {
    { 0x8b, 0x52, 0x7a, 0x6a, 0xeb, 0xda, 0xec, 0x9e,
      0xae, 0xf8, 0xed, 0xa2, 0xcb, 0x77, 0x83, 0xe5, },
    { 0x43, 0xfd, 0xaf, 0x53, 0xeb, 0xbc, 0x98, 0x80,
      0xc2, 0x28, 0x61, 0x7d, 0x6a, 0x9b, 0x54, 0x8b, },
    { 0x53, 0x78, 0x61, 0x04, 0xb9, 0x74, 0x4b, 0x98,
      0xf0, 0x52, 0xc4, 0x6f, 0x1c, 0x85, 0x0d, 0x0b, },
    { 0x43, 0xc9, 0xf7, 0xe6, 0x2f, 0x5d, 0x28, 0x8b,
      0xb2, 0x7a, 0xa4, 0x0e, 0xf8, 0xfe, 0x1e, 0xa8, },
    { 0x35, 0x80, 0xd1, 0x9c, 0xff, 0x44, 0xf1, 0x01,
      0x4a, 0x7c, 0x96, 0x6a, 0x69, 0x05, 0x9d, 0xe5, },
    { 0x80, 0x6d, 0xa8, 0x64, 0xdd, 0x29, 0xd4, 0x8d,
      0xea, 0xfb, 0xe7, 0x64, 0xf8, 0x20, 0x2a, 0xef, },
    { 0xdc, 0x43, 0xbe, 0x40, 0xbe, 0x0e, 0x53, 0x71,
      0x2f, 0x7e, 0x2b, 0xf5, 0xca, 0x70, 0x72, 0x09, },
    { 0x92, 0xbe, 0xed, 0xab, 0x18, 0x95, 0xa9, 0x4f,
      0xaa, 0x69, 0xb6, 0x32, 0xe5, 0xcc, 0x47, 0xce, },
    { 0x45, 0x92, 0x64, 0xf4, 0x79, 0x8f, 0x6a, 0x78,
      0xba, 0xcb, 0x89, 0xc1, 0x5e, 0xd3, 0xd6, 0x01, },
    { 0x90, 0x68, 0x4a, 0x2a, 0xc5, 0x5f, 0xe1, 0xec,
      0x2b, 0x8e, 0xbd, 0x56, 0x22, 0x52, 0x0b, 0x73, },
    { 0x74, 0x72, 0xf9, 0xa7, 0x98, 0x86, 0x07, 0xca,
      0x79, 0x70, 0x77, 0x95, 0x99, 0x10, 0x35, 0xe6, },
    { 0x56, 0xaf, 0xf0, 0x89, 0x87, 0x8b, 0xf3, 0x35,
      0x2f, 0x8d, 0xf1, 0x72, 0xa3, 0xae, 0x47, 0xd8, },
};

int aes_cbc()
{
    int ret;
    mbedtls_aes_context *ctx;
    size_t i, j;
    unsigned char output[16];
    unsigned char iv[16];

    if( ( ctx = (mbedtls_aes_context *)mbedtls_calloc( AES_CTX_COUNT,
                                    sizeof( mbedtls_aes_context ) ) ) == NULL )
    {
        mbedtls_printf( "  !  mbedtls_calloc() returned NULL\r\n" );
        return( -1 );
    }

    /* Initialise all context structures */
    for( i = 0; i < AES_CTX_COUNT; i++ )
        mbedtls_aes_init( &ctx[i] );

    /* Set keys */
    for( i = 0; i < AES_CTX_COUNT; i++ )
        if( ( ret = mbedtls_aes_setkey_enc( &ctx[i], keys[i], 128 ) ) != 0 )
        {
            mbedtls_printf( "  !  mbedtls_aes_setkey_enc() returned -0x%04X\r\n",
                            ret );
            goto exit;
        }

    /* Encrypt values... a few times */
    for( j = 0; j < REPETITIONS; j++ )
        for( i = 0; i < AES_CTX_COUNT; i++ )
        {
            memset( iv, 0x00, sizeof( iv ) );

            if( ( ret = mbedtls_aes_crypt_cbc( &ctx[i], MBEDTLS_AES_ENCRYPT,
                                               16, iv,
                                               inputs[i], output ) ) != 0 )
            {
                mbedtls_printf( "%d:  !  mbedtls_aes_crypt_cbc() returned "
                                "-0x%04X\r\n", __LINE__, ret );
                goto exit;
            }

            if( memcmp( output, results[i], 16 ) != 0 )
            {
                mbedtls_printf( "%d:  !  memcmp() result is not 0 at "
                                " repetition %u:%u\r\n",
                                __LINE__, j, i );
                ret = -2;
                goto exit;
            }
        }

    ret = 0;

exit:
    for( i = 0 ; i < AES_CTX_COUNT; i++ )
        mbedtls_aes_free( &ctx[i] );

    mbedtls_free( ctx );

    return( ret );
}

/*****************************************************************************/
/*******************************SHA1******************************************/
/*****************************************************************************/

#define SHA1_CTX_COUNT 10

unsigned char sha1_inputs[SHA1_CTX_COUNT][658] = {
    { },
    { 0xa8 },
    { 0x30, 0x00 },
    { 0x42, 0x74, 0x9e},
    { 0x9f, 0xc3, 0xfe, 0x08 },
    { 0xb5, 0xc1, 0xc6, 0xf1, 0xaf },
    { 0xec, 0x29, 0x56, 0x12, 0x44, 0xed, 0xe7, 0x06,
      0xb6, 0xeb, 0x30, 0xa1, 0xc3, 0x71, 0xd7, 0x44,
      0x50, 0xa1, 0x05, 0xc3, 0xf9, 0x73, 0x5f, 0x7f,
      0xa9, 0xfe, 0x38, 0xcf, 0x67, 0xf3, 0x04, 0xa5,
      0x73, 0x6a, 0x10, 0x6e, 0x92, 0xe1, 0x71, 0x39,
      0xa6, 0x81, 0x3b, 0x1c, 0x81, 0xa4, 0xf3, 0xd3,
      0xfb, 0x95, 0x46, 0xab, 0x42, 0x96, 0xfa, 0x9f,
      0x72, 0x28, 0x26, 0xc0, 0x66, 0x86, 0x9e, 0xda,
      0xcd, 0x73, 0xb2, 0x54, 0x80, 0x35, 0x18, 0x58,
      0x13, 0xe2, 0x26, 0x34, 0xa9, 0xda, 0x44, 0x00,
      0x0d, 0x95, 0xa2, 0x81, 0xff, 0x9f, 0x26, 0x4e,
      0xcc, 0xe0, 0xa9, 0x31, 0x22, 0x21, 0x62, 0xd0,
      0x21, 0xcc, 0xa2, 0x8d, 0xb5, 0xf3, 0xc2, 0xaa,
      0x24, 0x94, 0x5a, 0xb1, 0xe3, 0x1c, 0xb4, 0x13,
      0xae, 0x29, 0x81, 0x0f, 0xd7, 0x94, 0xca, 0xd5,
      0xdf, 0xaf, 0x29, 0xec, 0x43, 0xcb, 0x38, 0xd1,
      0x98, 0xfe, 0x4a, 0xe1, 0xda, 0x23, 0x59, 0x78,
      0x02, 0x21, 0x40, 0x5b, 0xd6, 0x71, 0x2a, 0x53,
      0x05, 0xda, 0x4b, 0x1b, 0x73, 0x7f, 0xce, 0x7c,
      0xd2, 0x1c, 0x0e, 0xb7, 0x72, 0x8d, 0x08, 0x23,
      0x5a, 0x90, 0x11, },
    { 0x5f, 0xc2, 0xc3, 0xf6, 0xa7, 0xe7, 0x9d, 0xc9,
      0x4b, 0xe5, 0x26, 0xe5, 0x16, 0x6a, 0x23, 0x88,
      0x99, 0xd5, 0x49, 0x27, 0xce, 0x47, 0x00, 0x18,
      0xfb, 0xfd, 0x66, 0x8f, 0xd9, 0xdd, 0x97, 0xcb,
      0xf6, 0x4e, 0x2c, 0x91, 0x58, 0x4d, 0x01, 0xda,
      0x63, 0xbe, 0x3c, 0xc9, 0xfd, 0xff, 0x8a, 0xdf,
      0xef, 0xc3, 0xac, 0x72, 0x8e, 0x1e, 0x33, 0x5b,
      0x9c, 0xdc, 0x87, 0xf0, 0x69, 0x17, 0x2e, 0x32,
      0x3d, 0x09, 0x4b, 0x47, 0xfa, 0x1e, 0x65, 0x2a,
      0xfe, 0x4d, 0x6a, 0xa1, 0x47, 0xa9, 0xf4, 0x6f,
      0xda, 0x33, 0xca, 0xcb, 0x65, 0xf3, 0xaa, 0x12,
      0x23, 0x47, 0x46, 0xb9, 0x00, 0x7a, 0x8c, 0x85,
      0xfe, 0x98, 0x2a, 0xfe, 0xd7, 0x81, 0x52, 0x21,
      0xe4, 0x3d, 0xba, 0x55, 0x3d, 0x8f, 0xe8, 0xa0,
      0x22, 0xcd, 0xac, 0x1b, 0x99, 0xee, 0xee, 0xa3,
      0x59, 0xe5, 0xa9, 0xd2, 0xe7, 0x2e, 0x38, 0x2d,
      0xff, 0xa6, 0xd1, 0x9f, 0x35, 0x9f, 0x4f, 0x27,
      0xdc, 0x34, 0x34, 0xcd, 0x27, 0xda, 0xee, 0xda,
      0x8e, 0x38, 0x59, 0x48, 0x73, 0x39, 0x86, 0x78,
      0x06, 0x5f, 0xbb, 0x23, 0x66, 0x5a, 0xba, 0x93,
      0x09, 0xd9, 0x46, 0x13, 0x5d, 0xa0, 0xe4, 0xa4,
      0xaf, 0xda, 0xdf, 0xf1, 0x4d, 0xb1, 0x8e, 0x85,
      0xe7, 0x1d, 0xd9, 0x3c, 0x3b, 0xf9, 0xfa, 0xf7,
      0xf2, 0x5c, 0x81, 0x94, 0xc4, 0x26, 0x9b, 0x1e,
      0xe3, 0xd9, 0x93, 0x40, 0x97, 0xab, 0x99, 0x00,
      0x25, 0xd9, 0xc3, 0xaa, 0xf6, 0x3d, 0x51, 0x09,
      0xf5, 0x23, 0x35, 0xdd, 0x39, 0x59, 0xd3, 0x8a,
      0xe4, 0x85, 0x05, 0x0e, 0x4b, 0xbb, 0x62, 0x35,
      0x57, 0x4f, 0xc0, 0x10, 0x2b, 0xe8, 0xf7, 0xa3,
      0x06, 0xd6, 0xe8, 0xde, 0x6b, 0xa6, 0xbe, 0xcf,
      0x80, 0xf3, 0x74, 0x15, 0xb5, 0x7f, 0x98, 0x98,
      0xa5, 0x82, 0x4e, 0x77, 0x41, 0x41, 0x97, 0x42,
      0x2b, 0xe3, 0xd3, 0x6a, 0x60, 0x80, },
    { 0x0f, 0x86, 0x5f, 0x46, 0xa8, 0xf3, 0xae, 0xd2,
      0xda, 0x18, 0x48, 0x2a, 0xa0, 0x9a, 0x8f, 0x39,
      0x0d, 0xc9, 0xda, 0x07, 0xd5, 0x1d, 0x1b, 0xd1,
      0x0f, 0xe0, 0xbf, 0x5f, 0x39, 0x28, 0xd5, 0x92,
      0x7d, 0x08, 0x73, 0x3d, 0x32, 0x07, 0x55, 0x35,
      0xa6, 0xd1, 0xc8, 0xac, 0x1b, 0x2d, 0xc6, 0xba,
      0x0f, 0x2f, 0x63, 0x3d, 0xc1, 0xaf, 0x68, 0xe3,
      0xf0, 0xfa, 0x3d, 0x85, 0xe6, 0xc6, 0x0c, 0xb7,
      0xb5, 0x6c, 0x23, 0x9d, 0xc1, 0x51, 0x9a, 0x00,
      0x7e, 0xa5, 0x36, 0xa0, 0x7b, 0x51, 0x8e, 0xcc,
      0xa0, 0x2a, 0x6c, 0x31, 0xb4, 0x6b, 0x76, 0xf0,
      0x21, 0x62, 0x0e, 0xf3, 0xfc, 0x69, 0x76, 0x80,
      0x40, 0x18, 0x38, 0x0e, 0x5a, 0xb9, 0xc5, 0x58,
      0xeb, 0xfc, 0x5c, 0xb1, 0xc9, 0xed, 0x2d, 0x97,
      0x47, 0x22, 0xbf, 0x8a, 0xb6, 0x39, 0x8f, 0x1f,
      0x2b, 0x82, 0xfa, 0x50, 0x83, 0xf8, 0x5c, 0x16,
      0xa5, 0x76, 0x7a, 0x3a, 0x07, 0x27, 0x1d, 0x67,
      0x74, 0x3f, 0x00, 0x85, 0x0c, 0xe8, 0xec, 0x42,
      0x8c, 0x7f, 0x22, 0xf1, 0xcf, 0x01, 0xf9, 0x98,
      0x95, 0xc0, 0xc8, 0x44, 0x84, 0x5b, 0x06, 0xa0,
      0x6c, 0xec, 0xb0, 0xc6, 0xcf, 0x83, 0xeb, 0x55,
      0xa1, 0xd4, 0xeb, 0xc4, 0x4c, 0x2c, 0x13, 0xf6,
      0xf7, 0xaa, 0x5e, 0x0e, 0x08, 0xab, 0xfd, 0x84,
      0xe7, 0x86, 0x42, 0x79, 0x05, 0x7a, 0xbc, 0x47,
      0x1e, 0xe4, 0xa4, 0x5d, 0xbb, 0xb5, 0x77, 0x4a,
      0xfa, 0x24, 0xe5, 0x17, 0x91, 0xa0, 0xea, 0xda,
      0x11, 0x09, 0x3b, 0x88, 0x68, 0x1f, 0xe3, 0x0b,
      0xaa, 0x3b, 0x2e, 0x94, 0x11, 0x3d, 0xc6, 0x33,
      0x42, 0xc5, 0x1c, 0xa5, 0xd1, 0xa6, 0x09, 0x6d,
      0x08, 0x97, 0xb6, 0x26, 0xe4, 0x2c, 0xb9, 0x17,
      0x61, 0x05, 0x80, 0x08, 0xf7, 0x46, 0xf3, 0x54,
      0x65, 0x46, 0x55, 0x40, 0xad, 0x8c, 0x6b, 0x8b,
      0x60, 0xf7, 0xe1, 0x46, 0x1b, 0x3c, 0xe9, 0xe6,
      0x52, 0x96, 0x25, 0x98, 0x4c, 0xb8, 0xc7, 0xd4,
      0x6f, 0x07, 0xf7, 0x35, 0xbe, 0x06, 0x75, 0x88,
      0xa0, 0x11, 0x7f, 0x23, 0xe3, 0x4f, 0xf5, 0x78,
      0x00, 0xe2, 0xbb, 0xe9, 0xa1, 0x60, 0x5f, 0xde,
      0x60, 0x87, 0xfb, 0x15, 0xd2, 0x2c, 0x5d, 0x3a,
      0xc4, 0x75, 0x66, 0xb8, 0xc4, 0x48, 0xb0, 0xce,
      0xe4, 0x03, 0x73, 0xe5, 0xba, 0x6e, 0xaa, 0x21,
      0xab, 0xee, 0x71, 0x36, 0x6a, 0xfb, 0xb2, 0x7d,
      0xbb, 0xd3, 0x00, 0x47, 0x7d, 0x70, 0xc3, 0x71,
      0xe7, 0xb8, 0x96, 0x38, 0x12, 0xf5, 0xed, 0x4f,
      0xb7, 0x84, 0xfb, 0x2f, 0x3b, 0xd1, 0xd3, 0xaf,
      0xe8, 0x83, 0xcd, 0xd4, 0x7e, 0xf3, 0x2b, 0xea,
      0xea, },
    { 0x82, 0x36, 0x15, 0x37, 0x81, 0xbd, 0x2f, 0x1b,
      0x81, 0xff, 0xe0, 0xde, 0xf1, 0xbe, 0xb4, 0x6f,
      0x5a, 0x70, 0x19, 0x11, 0x42, 0x92, 0x66, 0x51,
      0x50, 0x3f, 0x1b, 0x3b, 0xb1, 0x01, 0x6a, 0xcd,
      0xb9, 0xe7, 0xf7, 0xac, 0xce, 0xd8, 0xdd, 0x16,
      0x82, 0x26, 0xf1, 0x18, 0xff, 0x66, 0x4a, 0x01,
      0xa8, 0x80, 0x01, 0x16, 0xfd, 0x02, 0x35, 0x87,
      0xbf, 0xba, 0x52, 0xa2, 0x55, 0x83, 0x93, 0x47,
      0x6f, 0x5f, 0xc6, 0x9c, 0xe9, 0xc6, 0x50, 0x01,
      0xf2, 0x3e, 0x70, 0x47, 0x6d, 0x2c, 0xc8, 0x1c,
      0x97, 0xea, 0x19, 0xca, 0xeb, 0x19, 0x4e, 0x22,
      0x43, 0x39, 0xbc, 0xb2, 0x3f, 0x77, 0xa8, 0x3f,
      0xea, 0xc5, 0x09, 0x6f, 0x9b, 0x30, 0x90, 0xc5,
      0x1a, 0x6e, 0xe6, 0xd2, 0x04, 0xb7, 0x35, 0xaa,
      0x71, 0xd7, 0xe9, 0x96, 0xd3, 0x80, 0xb8, 0x08,
      0x22, 0xe4, 0xdf, 0xd4, 0x36, 0x83, 0xaf, 0x9c,
      0x74, 0x42, 0x49, 0x8c, 0xac, 0xbe, 0xa6, 0x48,
      0x42, 0xdf, 0xda, 0x23, 0x8c, 0xb0, 0x99, 0x92,
      0x7c, 0x6e, 0xfa, 0xe0, 0x7f, 0xdf, 0x7b, 0x23,
      0xa4, 0xe4, 0x45, 0x6e, 0x01, 0x52, 0xb2, 0x48,
      0x53, 0xfe, 0x0d, 0x5d, 0xe4, 0x17, 0x99, 0x74,
      0xb2, 0xb9, 0xd4, 0xa1, 0xcd, 0xbe, 0xfc, 0xbc,
      0x01, 0xd8, 0xd3, 0x11, 0xb5, 0xdd, 0xa0, 0x59,
      0x13, 0x61, 0x76, 0xea, 0x69, 0x8a, 0xb8, 0x2a,
      0xcf, 0x20, 0xdd, 0x49, 0x0b, 0xe4, 0x71, 0x30,
      0xb1, 0x23, 0x5c, 0xb4, 0x8f, 0x8a, 0x67, 0x10,
      0x47, 0x3c, 0xfc, 0x92, 0x3e, 0x22, 0x2d, 0x94,
      0xb5, 0x82, 0xf9, 0xae, 0x36, 0xd4, 0xca, 0x2a,
      0x32, 0xd1, 0x41, 0xb8, 0xe8, 0xcc, 0x36, 0x63,
      0x88, 0x45, 0xfb, 0xc4, 0x99, 0xbc, 0xe1, 0x76,
      0x98, 0xc3, 0xfe, 0xca, 0xe2, 0x57, 0x2d, 0xbb,
      0xd4, 0x70, 0x55, 0x24, 0x30, 0xd7, 0xef, 0x30,
      0xc2, 0x38, 0xc2, 0x12, 0x44, 0x78, 0xf1, 0xf7,
      0x80, 0x48, 0x38, 0x39, 0xb4, 0xfb, 0x73, 0xd6,
      0x3a, 0x94, 0x60, 0x20, 0x68, 0x24, 0xa5, 0xb6,
      0xb6, 0x53, 0x15, 0xb2, 0x1e, 0x3c, 0x2f, 0x24,
      0xc9, 0x7e, 0xe7, 0xc0, 0xe7, 0x8f, 0xaa, 0xd3,
      0xdf, 0x54, 0x9c, 0x7c, 0xa8, 0xef, 0x24, 0x18,
      0x76, 0xd9, 0xaa, 0xfe, 0x9a, 0x30, 0x9f, 0x6d,
      0xa3, 0x52, 0xbe, 0xc2, 0xca, 0xaa, 0x92, 0xee,
      0x8d, 0xca, 0x39, 0x28, 0x99, 0xba, 0x67, 0xdf,
      0xed, 0x90, 0xae, 0xf3, 0x3d, 0x41, 0xfc, 0x24,
      0x94, 0xb7, 0x65, 0xcb, 0x3e, 0x24, 0x22, 0xc8,
      0xe5, 0x95, 0xda, 0xbb, 0xfa, 0xca, 0x21, 0x77,
      0x57, 0x45, 0x3f, 0xb3, 0x22, 0xa1, 0x32, 0x03,
      0xf4, 0x25, 0xf6, 0x07, 0x3a, 0x99, 0x03, 0xe2,
      0xdc, 0x58, 0x18, 0xee, 0x1d, 0xa7, 0x37, 0xaf,
      0xc3, 0x45, 0xf0, 0x05, 0x77, 0x44, 0xe3, 0xa5,
      0x6e, 0x16, 0x81, 0xc9, 0x49, 0xeb, 0x12, 0x27,
      0x3a, 0x3b, 0xfc, 0x20, 0x69, 0x9e, 0x42, 0x3b,
      0x96, 0xe4, 0x4b, 0xd1, 0xff, 0x62, 0xe5, 0x0a,
      0x84, 0x8a, 0x89, 0x08, 0x09, 0xbf, 0xe1, 0x61,
      0x1c, 0x67, 0x87, 0xd3, 0xd7, 0x41, 0x10, 0x33,
      0x08, 0xf8, 0x49, 0xa7, 0x90, 0xf9, 0xc0, 0x15,
      0x09, 0x82, 0x86, 0xdb, 0xac, 0xfc, 0x34, 0xc1,
      0x71, 0x8b, 0x2c, 0x2b, 0x77, 0xe3, 0x21, 0x94,
      0xa7, 0x5d, 0xda, 0x37, 0x95, 0x4a, 0x32, 0x0f,
      0xa6, 0x87, 0x64, 0x02, 0x78, 0x52, 0x85, 0x5a,
      0x7e, 0x5b, 0x52, 0x74, 0xeb, 0x1e, 0x2c, 0xbc,
      0xd2, 0x71, 0x61, 0xd9, 0x8b, 0x59, 0xad, 0x24,
      0x58, 0x22, 0x01, 0x5f, 0x48, 0xaf, 0x82, 0xa4,
      0x5c, 0x0e, 0xd5, 0x9b, 0xe9, 0x4f, 0x9a, 0xf0,
      0x3d, 0x97, 0x36, 0x04, 0x85, 0x70, 0xd6, 0xe3,
      0xef, 0x63, 0xb1, 0x77, 0x0b, 0xc9, 0x8d, 0xfb,
      0x77, 0xde, 0x84, 0xb1, 0xbb, 0x17, 0x08, 0xd8,
      0x72, 0xb6, 0x25, 0xd9, 0xab, 0x9b, 0x06, 0xc1,
      0x8e, 0x5d, 0xbb, 0xf3, 0x43, 0x99, 0x39, 0x1f,
      0x0f, 0x8a, 0xa2, 0x6e, 0xc0, 0xda, 0xc7, 0xff,
      0x4c, 0xb8, 0xec, 0x97, 0xb5, 0x2b, 0xcb, 0x94,
      0x2f, 0xa6, 0xdb, 0x23, 0x85, 0xdc, 0xd1, 0xb3,
      0xb9, 0xd5, 0x67, 0xaa, 0xeb, 0x42, 0x5d, 0x56,
      0x7b, 0x0e, 0xbe, 0x26, 0x72, 0x35, 0x65, 0x1a,
      0x1e, 0xd9, 0xbf, 0x78, 0xfd, 0x93, 0xd3, 0xc1,
      0xdd, 0x07, 0x7f, 0xe3, 0x40, 0xbb, 0x04, 0xb0,
      0x05, 0x29, 0xc5, 0x8f, 0x45, 0x12, 0x4b, 0x71,
      0x7c, 0x16, 0x8d, 0x07, 0xe9, 0x82, 0x6e, 0x33,
      0x37, 0x69, 0x88, 0xbc, 0x5c, 0xf6, 0x28, 0x45,
      0xc2, 0x00, 0x99, 0x80, 0xa4, 0xdf, 0xa6, 0x9f,
      0xbc, 0x7e, 0x5a, 0x0b, 0x1b, 0xb2, 0x0a, 0x59,
      0x58, 0xca, 0x96, 0x7a, 0xec, 0x68, 0xeb, 0x31,
      0xdd, 0x8f, 0xcc, 0xca, 0x9a, 0xfc, 0xd3, 0x0a,
      0x26, 0xba, 0xb2, 0x62, 0x79, 0xf1, 0xbf, 0x67,
      0x24, 0xff, },
};

size_t sha1_ilens[SHA1_CTX_COUNT] = {
    0, 1, 2, 3, 4, 5, 163, 262, 361, 658,
};

unsigned char sha1_results[SHA1_CTX_COUNT][20] = {
    { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
      0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
      0xaf, 0xd8, 0x07, 0x09, },
    { 0x99, 0xf2, 0xaa, 0x95, 0xe3, 0x6f, 0x95, 0xc2,
      0xac, 0xb0, 0xea, 0xf2, 0x39, 0x98, 0xf0, 0x30,
      0x63, 0x8f, 0x3f, 0x15, },
    { 0xf9, 0x44, 0xdc, 0xd6, 0x35, 0xf9, 0x80, 0x1f,
      0x7a, 0xc9, 0x0a, 0x40, 0x7f, 0xbc, 0x47, 0x99,
      0x64, 0xde, 0xc0, 0x24, },
    { 0xa4, 0x44, 0x31, 0x9e, 0x9b, 0x6c, 0xc1, 0xe8,
      0x46, 0x4c, 0x51, 0x1e, 0xc0, 0x96, 0x9c, 0x37,
      0xd6, 0xbb, 0x26, 0x19, },
    { 0x16, 0xa0, 0xff, 0x84, 0xfc, 0xc1, 0x56, 0xfd,
      0x5d, 0x3c, 0xa3, 0xa7, 0x44, 0xf2, 0x0a, 0x23,
      0x2d, 0x17, 0x22, 0x53, },
    { 0xfe, 0xc9, 0xde, 0xeb, 0xfc, 0xde, 0xda, 0xf6,
      0x6d, 0xda, 0x52, 0x5e, 0x1b, 0xe4, 0x35, 0x97,
      0xa7, 0x3a, 0x1f, 0x93, },
    { 0x97, 0x01, 0x11, 0xc4, 0xe7, 0x7b, 0xcc, 0x88,
      0xcc, 0x20, 0x45, 0x9c, 0x02, 0xb6, 0x9b, 0x4a,
      0xa8, 0xf5, 0x82, 0x17, },
    { 0x04, 0x23, 0xdc, 0x76, 0xa8, 0x79, 0x11, 0x07,
      0xd1, 0x4e, 0x13, 0xf5, 0x26, 0x5b, 0x34, 0x3f,
      0x24, 0xcc, 0x0f, 0x19, },
    { 0x66, 0x92, 0xa7, 0x1d, 0x73, 0xe0, 0x0f, 0x27,
      0xdf, 0x97, 0x6b, 0xc5, 0x6d, 0xf4, 0x97, 0x06,
      0x50, 0xd9, 0x0e, 0x45, },
    { 0x11, 0x86, 0x3b, 0x48, 0x38, 0x09, 0xef, 0x88,
      0x41, 0x3c, 0xa9, 0xb0, 0x08, 0x4a, 0xc4, 0xa5,
      0x39, 0x06, 0x40, 0xaf, },
};

#define SPLIT 5

int sha1()
{
    int ret, next;
    size_t i, j;
    mbedtls_sha1_context *ctx;
    unsigned char output[20];
    size_t proc_len[SHA1_CTX_COUNT];
    size_t next_len;

    if( ( ctx = (mbedtls_sha1_context *)mbedtls_calloc( SHA1_CTX_COUNT,
                                    sizeof( mbedtls_sha1_context ) ) ) == NULL )
    {
        mbedtls_printf( "  !  mbedtls_calloc() return NULL\r\n" );
        return( -1 );
    }

    /* Initialise all context structures */
    for( i = 0; i < SHA1_CTX_COUNT; i++ )
        mbedtls_sha1_init( &ctx[i] );

    for( j = 1; j < REPETITIONS; j++ )
    {
        /* Start the contexts */
        for( i = 0; i < SHA1_CTX_COUNT; i++ )
            mbedtls_sha1_starts( &ctx[i] );

        memset( proc_len, 0, sizeof( proc_len ) );

        do
        {
            next = 0;

            for( i = 0; i < SHA1_CTX_COUNT; i++ )
            {
                /* Nothing left to do */
                if( proc_len[i] == sha1_ilens[i] )
                    continue;

                next = 1;

                next_len = sha1_ilens[i] / SPLIT + 1;
                next_len = ( next_len + proc_len[i] <= sha1_ilens[i] ) ? next_len :
                            sha1_ilens[i] - proc_len[i];

                mbedtls_sha1_update( &ctx[i], sha1_inputs[i] + proc_len[i],
                                    next_len );
                proc_len[i] += next_len;
            }
        }
        while( next == 1 );

        /* Verify the outputs */
        for( i = 0; i < SHA1_CTX_COUNT; i++ )
        {
            mbedtls_sha1_finish( &ctx[i], output );

            if( memcmp( output, sha1_results[i], sizeof( output ) ) != 0 )
            {
                mbedtls_printf( "%d:  !  memcmp() result is not 0 at "
                                " repetition %u:%u\r\n",
                                __LINE__, j, i );
                ret = -2;
                goto exit;
            }
        }
    }

    ret = 0;

exit:
    for( i = 0; i < SHA1_CTX_COUNT; i++ )
        mbedtls_sha1_free( &ctx[i] );

    mbedtls_free( ctx );

    return( ret );
}

/*****************************************************************************/
/*******************************SHA256****************************************/
/*****************************************************************************/

#define SHA256_CTX_COUNT 7

unsigned char sha256_inputs[SHA256_CTX_COUNT][955] = {
    { },
    { 0xbd },
    { 0x5f, 0xd4 },
    { 0xb0, 0xbd, 0x69 },
    { 0xc9, 0x8c, 0x8e, 0x55, },
    { 0x81, 0xa7, 0x23, 0xd9, 0x66, },
    { 0x83, 0x90, 0xcf, 0x0b, 0xe0, 0x76, 0x61, 0xcc,
      0x76, 0x69, 0xaa, 0xc5, 0x4c, 0xe0, 0x9a, 0x37,
      0x73, 0x3a, 0x62, 0x9d, 0x45, 0xf5, 0xd9, 0x83,
      0xef, 0x20, 0x1f, 0x9b, 0x2d, 0x13, 0x80, 0x0e,
      0x55, 0x5d, 0x9b, 0x10, 0x97, 0xfe, 0xc3, 0xb7,
      0x83, 0xd7, 0xa5, 0x0d, 0xcb, 0x5e, 0x2b, 0x64,
      0x4b, 0x96, 0xa1, 0xe9, 0x46, 0x3f, 0x17, 0x7c,
      0xf3, 0x49, 0x06, 0xbf, 0x38, 0x8f, 0x36, 0x6d,
      0xb5, 0xc2, 0xde, 0xee, 0x04, 0xa3, 0x0e, 0x28,
      0x3f, 0x76, 0x4a, 0x97, 0xc3, 0xb3, 0x77, 0xa0,
      0x34, 0xfe, 0xfc, 0x22, 0xc2, 0x59, 0x21, 0x4f,
      0xaa, 0x99, 0xba, 0xba, 0xff, 0x16, 0x0a, 0xb0,
      0xaa, 0xa7, 0xe2, 0xcc, 0xb0, 0xce, 0x09, 0xc6,
      0xb3, 0x2f, 0xe0, 0x8c, 0xbc, 0x47, 0x46, 0x94,
      0x37, 0x5a, 0xba, 0x70, 0x3f, 0xad, 0xbf, 0xa3,
      0x1c, 0xf6, 0x85, 0xb3, 0x0a, 0x11, 0xc5, 0x7f,
      0x3c, 0xf4, 0xed, 0xd3, 0x21, 0xe5, 0x7d, 0x3a,
      0xe6, 0xeb, 0xb1, 0x13, 0x3c, 0x82, 0x60, 0xe7,
      0x5b, 0x92, 0x24, 0xfa, 0x47, 0xa2, 0xbb, 0x20,
      0x52, 0x49, 0xad, 0xd2, 0xe2, 0xe6, 0x2f, 0x81,
      0x74, 0x91, 0x48, 0x2a, 0xe1, 0x52, 0x32, 0x2b,
      0xe0, 0x90, 0x03, 0x55, 0xcd, 0xcc, 0x8d, 0x42,
      0xa9, 0x8f, 0x82, 0xe9, 0x61, 0xa0, 0xdc, 0x6f,
      0x53, 0x7b, 0x7b, 0x41, 0x0e, 0xff, 0x10, 0x5f,
      0x59, 0x67, 0x3b, 0xfb, 0x78, 0x7b, 0xf0, 0x42,
      0xaa, 0x07, 0x1f, 0x7a, 0xf6, 0x8d, 0x94, 0x4d,
      0x27, 0x37, 0x1c, 0x64, 0x16, 0x0f, 0xe9, 0x38,
      0x27, 0x72, 0x37, 0x25, 0x16, 0xc2, 0x30, 0xc1,
      0xf4, 0x5c, 0x0d, 0x6b, 0x6c, 0xca, 0x7f, 0x27,
      0x4b, 0x39, 0x4d, 0xa9, 0x40, 0x2d, 0x3e, 0xaf,
      0xdf, 0x73, 0x39, 0x94, 0xec, 0x58, 0xab, 0x22,
      0xd7, 0x18, 0x29, 0xa9, 0x83, 0x99, 0x57, 0x4d,
      0x4b, 0x59, 0x08, 0xa4, 0x47, 0xa5, 0xa6, 0x81,
      0xcb, 0x0d, 0xd5, 0x0a, 0x31, 0x14, 0x53, 0x11,
      0xd9, 0x2c, 0x22, 0xa1, 0x6d, 0xe1, 0xea, 0xd6,
      0x6a, 0x54, 0x99, 0xf2, 0xdc, 0xeb, 0x4c, 0xae,
      0x69, 0x47, 0x72, 0xce, 0x90, 0x76, 0x2e, 0xf8,
      0x33, 0x6a, 0xfe, 0xc6, 0x53, 0xaa, 0x9b, 0x1a,
      0x1c, 0x48, 0x20, 0xb2, 0x21, 0x13, 0x6d, 0xfc,
      0xe8, 0x0d, 0xce, 0x2b, 0xa9, 0x20, 0xd8, 0x8a,
      0x53, 0x0c, 0x94, 0x10, 0xd0, 0xa4, 0xe0, 0x35,
      0x8a, 0x3a, 0x11, 0x05, 0x2e, 0x58, 0xdd, 0x73,
      0xb0, 0xb1, 0x79, 0xef, 0x8f, 0x56, 0xfe, 0x3b,
      0x5a, 0x2d, 0x11, 0x7a, 0x73, 0xa0, 0xc3, 0x8a,
      0x13, 0x92, 0xb6, 0x93, 0x8e, 0x97, 0x82, 0xe0,
      0xd8, 0x64, 0x56, 0xee, 0x48, 0x84, 0xe3, 0xc3,
      0x9d, 0x4d, 0x75, 0x81, 0x3f, 0x13, 0x63, 0x3b,
      0xc7, 0x9b, 0xaa, 0x07, 0xc0, 0xd2, 0xd5, 0x55,
      0xaf, 0xbf, 0x20, 0x7f, 0x52, 0xb7, 0xdc, 0xa1,
      0x26, 0xd0, 0x15, 0xaa, 0x2b, 0x98, 0x73, 0xb3,
      0xeb, 0x06, 0x5e, 0x90, 0xb9, 0xb0, 0x65, 0xa5,
      0x37, 0x3f, 0xe1, 0xfb, 0x1b, 0x20, 0xd5, 0x94,
      0x32, 0x7d, 0x19, 0xfb, 0xa5, 0x6c, 0xb8, 0x1e,
      0x7b, 0x66, 0x96, 0x60, 0x5f, 0xfa, 0x56, 0xeb,
      0xa3, 0xc2, 0x7a, 0x43, 0x86, 0x97, 0xcc, 0x21,
      0xb2, 0x01, 0xfd, 0x7e, 0x09, 0xf1, 0x8d, 0xee,
      0xa1, 0xb3, 0xea, 0x2f, 0x0d, 0x1e, 0xdc, 0x02,
      0xdf, 0x0e, 0x20, 0x39, 0x6a, 0x14, 0x54, 0x12,
      0xcd, 0x6b, 0x13, 0xc3, 0x2d, 0x2e, 0x60, 0x56,
      0x41, 0xc9, 0x48, 0xb7, 0x14, 0xae, 0xc3, 0x0c,
      0x06, 0x49, 0xdc, 0x44, 0x14, 0x35, 0x11, 0xf3,
      0x5a, 0xb0, 0xfd, 0x5d, 0xd6, 0x4c, 0x34, 0xd0,
      0x6f, 0xe8, 0x6f, 0x38, 0x36, 0xdf, 0xe9, 0xed,
      0xeb, 0x7f, 0x08, 0xcf, 0xc3, 0xbd, 0x40, 0x95,
      0x68, 0x26, 0x35, 0x62, 0x42, 0x19, 0x1f, 0x99,
      0xf5, 0x34, 0x73, 0xf3, 0x2b, 0x0c, 0xc0, 0xcf,
      0x93, 0x21, 0xd6, 0xc9, 0x2a, 0x11, 0x2e, 0x8d,
      0xb9, 0x0b, 0x86, 0xee, 0x9e, 0x87, 0xcc, 0x32,
      0xd0, 0x34, 0x3d, 0xb0, 0x1e, 0x32, 0xce, 0x9e,
      0xb7, 0x82, 0xcb, 0x24, 0xef, 0xbb, 0xbe, 0xb4,
      0x40, 0xfe, 0x92, 0x9e, 0x8f, 0x2b, 0xf8, 0xdf,
      0xb1, 0x55, 0x0a, 0x3a, 0x2e, 0x74, 0x2e, 0x8b,
      0x45, 0x5a, 0x3e, 0x57, 0x30, 0xe9, 0xe6, 0xa7,
      0xa9, 0x82, 0x4d, 0x17, 0xac, 0xc0, 0xf7, 0x2a,
      0x7f, 0x67, 0xea, 0xe0, 0xf0, 0x97, 0x0f, 0x8b,
      0xde, 0x46, 0xdc, 0xde, 0xfa, 0xed, 0x30, 0x47,
      0xcf, 0x80, 0x7e, 0x7f, 0x00, 0xa4, 0x2e, 0x5f,
      0xd1, 0x1d, 0x40, 0xf5, 0xe9, 0x85, 0x33, 0xd7,
      0x57, 0x44, 0x25, 0xb7, 0xd2, 0xbc, 0x3b, 0x38,
      0x45, 0xc4, 0x43, 0x00, 0x8b, 0x58, 0x98, 0x0e,
      0x76, 0x8e, 0x46, 0x4e, 0x17, 0xcc, 0x6f, 0x6b,
      0x39, 0x39, 0xee, 0xe5, 0x2f, 0x71, 0x39, 0x63,
      0xd0, 0x7d, 0x8c, 0x4a, 0xbf, 0x02, 0x44, 0x8e,
      0xf0, 0xb8, 0x89, 0xc9, 0x67, 0x1e, 0x2f, 0x8a,
      0x43, 0x6d, 0xde, 0xef, 0xfc, 0xca, 0x71, 0x76,
      0xe9, 0xbf, 0x9d, 0x10, 0x05, 0xec, 0xd3, 0x77,
      0xf2, 0xfa, 0x67, 0xc2, 0x3e, 0xd1, 0xf1, 0x37,
      0xe6, 0x0b, 0xf4, 0x60, 0x18, 0xa8, 0xbd, 0x61,
      0x3d, 0x03, 0x8e, 0x88, 0x37, 0x04, 0xfc, 0x26,
      0xe7, 0x98, 0x96, 0x9d, 0xf3, 0x5e, 0xc7, 0xbb,
      0xc6, 0xa4, 0xfe, 0x46, 0xd8, 0x91, 0x0b, 0xd8,
      0x2f, 0xa3, 0xcd, 0xed, 0x26, 0x5d, 0x0a, 0x3b,
      0x6d, 0x39, 0x9e, 0x42, 0x51, 0xe4, 0xd8, 0x23,
      0x3d, 0xaa, 0x21, 0xb5, 0x81, 0x2f, 0xde, 0xd6,
      0x53, 0x61, 0x98, 0xff, 0x13, 0xaa, 0x5a, 0x1c,
      0xd4, 0x6a, 0x5b, 0x9a, 0x17, 0xa4, 0xdd, 0xc1,
      0xd9, 0xf8, 0x55, 0x44, 0xd1, 0xd1, 0xcc, 0x16,
      0xf3, 0xdf, 0x85, 0x80, 0x38, 0xc8, 0xe0, 0x71,
      0xa1, 0x1a, 0x7e, 0x15, 0x7a, 0x85, 0xa6, 0xa8,
      0xdc, 0x47, 0xe8, 0x8d, 0x75, 0xe7, 0x00, 0x9a,
      0x8b, 0x26, 0xfd, 0xb7, 0x3f, 0x33, 0xa2, 0xa7,
      0x0f, 0x1e, 0x0c, 0x25, 0x9f, 0x8f, 0x95, 0x33,
      0xb9, 0xb8, 0xf9, 0xaf, 0x92, 0x88, 0xb7, 0x27,
      0x4f, 0x21, 0xba, 0xee, 0xc7, 0x8d, 0x39, 0x6f,
      0x8b, 0xac, 0xdc, 0xc2, 0x24, 0x71, 0x20, 0x7d,
      0x9b, 0x4e, 0xfc, 0xcd, 0x3f, 0xed, 0xc5, 0xc5,
      0xa2, 0x21, 0x4f, 0xf5, 0xe5, 0x1c, 0x55, 0x3f,
      0x35, 0xe2, 0x1a, 0xe6, 0x96, 0xfe, 0x51, 0xe8,
      0xdf, 0x73, 0x3a, 0x8e, 0x06, 0xf5, 0x0f, 0x41,
      0x9e, 0x59, 0x9e, 0x9f, 0x9e, 0x4b, 0x37, 0xce,
      0x64, 0x3f, 0xc8, 0x10, 0xfa, 0xaa, 0x47, 0x98,
      0x97, 0x71, 0x50, 0x9d, 0x69, 0xa1, 0x10, 0xac,
      0x91, 0x62, 0x61, 0x42, 0x70, 0x26, 0x36, 0x9a,
      0x21, 0x26, 0x3a, 0xc4, 0x46, 0x0f, 0xb4, 0xf7,
      0x08, 0xf8, 0xae, 0x28, 0x59, 0x98, 0x56, 0xdb,
      0x7c, 0xb6, 0xa4, 0x3a, 0xc8, 0xe0, 0x3d, 0x64,
      0xa9, 0x60, 0x98, 0x07, 0xe7, 0x6c, 0x5f, 0x31,
      0x2b, 0x9d, 0x18, 0x63, 0xbf, 0xa3, 0x04, 0xe8,
      0x95, 0x36, 0x47, 0x64, 0x8b, 0x4f, 0x4a, 0xb0,
      0xed, 0x99, 0x5e, },
};

size_t sha256_ilens[SHA256_CTX_COUNT] = {
    0, 1, 2, 3, 4, 5, 955
};

unsigned char sha256_results[SHA256_CTX_COUNT][32] = {
    { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
      0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
      0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
      0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, },
    { 0x68, 0x32, 0x57, 0x20, 0xaa, 0xbd, 0x7c, 0x82,
      0xf3, 0x0f, 0x55, 0x4b, 0x31, 0x3d, 0x05, 0x70,
      0xc9, 0x5a, 0xcc, 0xbb, 0x7d, 0xc4, 0xb5, 0xaa,
      0xe1, 0x12, 0x04, 0xc0, 0x8f, 0xfe, 0x73, 0x2b, },
    { 0x7c, 0x4f, 0xbf, 0x48, 0x44, 0x98, 0xd2, 0x1b,
      0x48, 0x7b, 0x9d, 0x61, 0xde, 0x89, 0x14, 0xb2,
      0xea, 0xda, 0xf2, 0x69, 0x87, 0x12, 0x93, 0x6d,
      0x47, 0xc3, 0xad, 0xa2, 0x55, 0x8f, 0x67, 0x88, },
    { 0x40, 0x96, 0x80, 0x42, 0x21, 0x09, 0x3d, 0xdc,
      0xcf, 0xbf, 0x46, 0x83, 0x14, 0x90, 0xea, 0x63,
      0xe9, 0xe9, 0x94, 0x14, 0x85, 0x8f, 0x8d, 0x75,
      0xff, 0x7f, 0x64, 0x2c, 0x7c, 0xa6, 0x18, 0x03, },
    { 0x7a, 0xbc, 0x22, 0xc0, 0xae, 0x5a, 0xf2, 0x6c,
      0xe9, 0x3d, 0xbb, 0x94, 0x43, 0x3a, 0x0e, 0x0b,
      0x2e, 0x11, 0x9d, 0x01, 0x4f, 0x8e, 0x7f, 0x65,
      0xbd, 0x56, 0xc6, 0x1c, 0xcc, 0xcd, 0x95, 0x04, },
    { 0x75, 0x16, 0xfb, 0x8b, 0xb1, 0x13, 0x50, 0xdf,
      0x2b, 0xf3, 0x86, 0xbc, 0x3c, 0x33, 0xbd, 0x0f,
      0x52, 0xcb, 0x4c, 0x67, 0xc6, 0xe4, 0x74, 0x5e,
      0x04, 0x88, 0xe6, 0x2c, 0x2a, 0xea, 0x26, 0x05, },
    { 0x41, 0x09, 0xcd, 0xbe, 0xc3, 0x24, 0x0a, 0xd7,
      0x4c, 0xc6, 0xc3, 0x7f, 0x39, 0x30, 0x0f, 0x70,
      0xfe, 0xde, 0x16, 0xe2, 0x1e, 0xfc, 0x77, 0xf7,
      0x86, 0x59, 0x98, 0x71, 0x4a, 0xad, 0x0b, 0x5e, },
};

int sha256()
{
    int ret, next;
    size_t i, j;
    mbedtls_sha256_context *ctx;
    unsigned char output[32];
    size_t proc_len[SHA256_CTX_COUNT];
    size_t next_len;

    if( ( ctx = (mbedtls_sha256_context *)mbedtls_calloc( SHA256_CTX_COUNT,
                                    sizeof( mbedtls_sha256_context ) ) ) == NULL )
    {
        mbedtls_printf( "  !  mbedtls_calloc() return NULL\r\n" );
        return( -1 );
    }

    /* Initialise all context structures */
    for( i = 0; i < SHA256_CTX_COUNT; i++ )
        mbedtls_sha256_init( &ctx[i] );

    for( j = 1; j < REPETITIONS; j++ )
    {
        /* Start the contexts */
        for( i = 0; i < SHA256_CTX_COUNT; i++ )
            mbedtls_sha256_starts( &ctx[i], 0 );

        memset( proc_len, 0, sizeof( proc_len ) );

        do
        {
            next = 0;

            for( i = 0; i < SHA256_CTX_COUNT; i++ )
            {
                /* Nothing left to do */
                if( proc_len[i] == sha256_ilens[i] )
                    continue;

                next = 1;

                next_len = sha256_ilens[i] / SPLIT + 1;
                next_len = ( next_len + proc_len[i] <= sha256_ilens[i] ) ? next_len :
                            sha256_ilens[i] - proc_len[i];

                mbedtls_sha256_update( &ctx[i], sha256_inputs[i] + proc_len[i],
                                    next_len );
                proc_len[i] += next_len;
            }
        }
        while( next == 1 );

        /* Verify the outputs */
        for( i = 0; i < SHA256_CTX_COUNT; i++ )
        {
            mbedtls_sha256_finish( &ctx[i], output );

            if( memcmp( output, sha256_results[i], sizeof( output ) ) != 0 )
            {
                mbedtls_printf( "%d:  !  memcmp() result is not 0 at "
                                " repetition %u:%u\r\n",
                                __LINE__, j, i );
                ret = -2;
                goto exit;
            }
        }
    }

    ret = 0;

exit:
    for( i = 0; i < SHA256_CTX_COUNT; i++ )
        mbedtls_sha256_free( &ctx[i] );

    mbedtls_free( ctx );

    return( ret );
}

/*****************************************************************************/
/*******************************MD5*******************************************/
/*****************************************************************************/

#define MD5_CTX_COUNT 7

unsigned char md5_inputs[MD5_CTX_COUNT][80] = {
    { },
    { 0x61 },
    { 0x61, 0x62, 0x63 },
    { 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
      0x64, 0x69, 0x67, 0x65, 0x73, 0x74 },
    { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
      0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
      0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
      0x79, 0x7a },
    { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
      0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
      0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
      0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
      0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
      0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
      0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
      0x34, 0x35, 0x36, 0x37, 0x38, 0x39 },
    { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
      0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
      0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
      0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
      0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
      0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
      0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
      0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
      0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 },
};

size_t md5_ilens[MD5_CTX_COUNT] = {
    0, 1, 3, 14, 26, 62, 80,
};

unsigned char md5_results[MD5_CTX_COUNT][16] = {
    { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
      0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, },
    { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
      0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61, },
    { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
      0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72, },
    { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
      0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0, },
    { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
      0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b, },
    { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
      0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f, },
    { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
      0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a, },
};

int md5()
{
    int ret, next;
    size_t i, j;
    mbedtls_md5_context *ctx;
    unsigned char output[16];
    size_t proc_len[MD5_CTX_COUNT];
    size_t next_len;

    if( ( ctx = (mbedtls_md5_context *)mbedtls_calloc( MD5_CTX_COUNT,
                                    sizeof( mbedtls_md5_context ) ) ) == NULL )
    {
        mbedtls_printf( "  !  mbedtls_calloc() return NULL\r\n" );
        return( -1 );
    }

    /* Initialise all context structures */
    for( i = 0; i < MD5_CTX_COUNT; i++ )
        mbedtls_md5_init( &ctx[i] );

    for( j = 1; j < REPETITIONS; j++ )
    {
        /* Start the contexts */
        for( i = 0; i < MD5_CTX_COUNT; i++ )
            mbedtls_md5_starts( &ctx[i] );

        memset( proc_len, 0, sizeof( proc_len ) );

        do
        {
            next = 0;

            for( i = 0; i < MD5_CTX_COUNT; i++ )
            {
                /* Nothing left to do */
                if( proc_len[i] == md5_ilens[i] )
                    continue;

                next = 1;

                next_len = md5_ilens[i] / SPLIT + 1;
                next_len = ( next_len + proc_len[i] <= md5_ilens[i] ) ? next_len :
                            md5_ilens[i] - proc_len[i];

                mbedtls_md5_update( &ctx[i], md5_inputs[i] + proc_len[i],
                                    next_len );
                proc_len[i] += next_len;
            }
        }
        while( next == 1 );

        /* Verify the outputs */
        for( i = 0; i < MD5_CTX_COUNT; i++ )
        {
            mbedtls_md5_finish( &ctx[i], output );

            if( memcmp( output, md5_results[i], sizeof( output ) ) != 0 )
            {
                mbedtls_printf( "%d:  !  memcmp() result is not 0 at "
                                " repetition %u:%u\r\n",
                                __LINE__, j, i );
                ret = -2;
                goto exit;
            }
        }
    }

    ret = 0;

exit:
    for( i = 0; i < MD5_CTX_COUNT; i++ )
        mbedtls_md5_free( &ctx[i] );

    mbedtls_free( ctx );

    return( ret );
}

int main()
{
    int ret;
    int exit_code = MBEDTLS_EXIT_FAILURE;

    if( ( ret = aes_cbc() ) != 0 )
        mbedtls_printf( "failed\r\n  ! AES-CBC returned %d\r\n", ret );
    if( ( ret = sha1() ) != 0 )
        mbedtls_printf( "failed\r\n  ! SHA-1 returned %d\r\n", ret );
    if( ( ret = sha256() ) != 0 )
        mbedtls_printf( "failed\r\n  ! SHA-256 returned %d\r\n", ret );
    if( ( ret = md5() ) != 0 )
        mbedtls_printf( "failed\r\n  ! MD5 returned %d\r\n", ret );

    if( ret != 0 )
        mbedtls_printf( "FAIL\r\n" );
    else
    {
        mbedtls_printf( "DONE\r\n" );
        exit_code = MBEDTLS_EXIT_SUCCESS;
    }

    return( exit_code );
}

Bug

Target
STM32F439xI family of devices with hardware acceleration enabled

Toolchain:
GCC_ARM

mbed-os sha:
5e437fe

Expected behavior
The test should succeed.

Actual behavior
The tests for MD5, SHA1 and SHA256 fail

Steps to reproduce
Compile and run the test above in a STM32F439xI device, e.g. UBLOX_EVK_ODIN_W2. The failures will be printed in the serial terminal.

@andresag01
Copy link
Author

@RonEld @adustm @yanesca @sbutcher-arm

andresag01 pushed a commit to andresag01/mbed that referenced this issue Sep 12, 2017
STM32F439xI-family MD5, SHA1 and SHA256 hardware acceleration
occasionally produces incorrect output (ARMmbed#5079).

Don't enable MD5, SHA1 and SHA256 HW acceleration on STM32F439xI-family
targets by default until issue ARMmbed#5079 is fixed.
@andresag01
Copy link
Author

I have created PR #5080 that disables HW acceleration for the relevant primitives. This is only a workaround though.

@andresag01
Copy link
Author

andresag01 commented Sep 12, 2017

@adustm: My understanding is that the following targets all share the same hardware acceleration code:

  • TARGET_STM32F4/
  • TARGET_STM32F7/
  • TARGET_STM32L4/

Do you think they all have similar issues? Unfortunately I do not have the hardware to test them all and report my findings...

@adustm
Copy link
Member

adustm commented Sep 12, 2017

Hello @andresag01
Thanks for reporting the issue, I'll have to understand the reason for these failure (especially the SHA256 that is not failing with TESTS/mbedtls/multi/main.cpp)

I filnalize the AES then I come back on this one.

I'll check at the same time the behavior of other families.

kind regards

@adustm
Copy link
Member

adustm commented Sep 12, 2017

By the way, Mihail has all the platforms you are missing :)

@andresag01
Copy link
Author

@adustm:

Thanks for reporting the issue... I filnalize the AES then I come back on this one

Many thanks for taking a look. Please let me know if there is anything else I can do to help.

I'll have to understand the reason for these failure (especially the SHA256 that is not failing with TESTS/mbedtls/multi/main.cpp)

Thats a very good point, I had not considered that... My guess is that the test I am currently using is slightly more stressful and uses at least double the amount of contexts. Also, there is a lot of interleaving. Of course, there is also a chance that I made a mistake in the test, but I havent found any indication of this yet.

Mihail has all the platforms you are missing

Thanks for letting me know! I will speak with Mihail's team and see what I can get

I'll check at the same time the behavior of other families.

Thanks for checking this. I think that would be ideal given that the code is mostly shared between all the devices. I will also try to get a hold of the boards and run a couple of quick tests myself.

adbridge pushed a commit that referenced this issue Sep 24, 2017
STM32F439xI-family MD5, SHA1 and SHA256 hardware acceleration
occasionally produces incorrect output (#5079).

Don't enable MD5, SHA1 and SHA256 HW acceleration on STM32F439xI-family
targets by default until issue #5079 is fixed.
@kjbracey
Copy link
Contributor

kjbracey commented Oct 5, 2017

In case it's useful, I've was seeing failures of DTLS/UDP handshakes against mbed Cloud server on the Ublox Odin W2. On 5.6.0, with the crypto acceleration enabled, it fails, but on 5.6.1 with it disabled it works.

But what's odd, and that I can't explain is that TLS/TCP handshakes did actually work on the same system in 5.6.0 with the hardware crypto enabled.

I can't see any difference in what mbed TLS is doing between DTLS and TLS with regards to the calls to crypto. My current best guess is an alignment difference, but I'm far from certain of that. So when you have a fix for the interleaving, I'd be interested in checking it on that DTLS case - I am wondering if the failure cause is something other than interleaving that you've yet to discover.

My second concern is that looking at #5018, I see protection against interleaved crypto operations on a single thread, but I'm not seeing any multithreading protection - doesn't it need a mutex to prevent a second thread touching the hardware between your "restore context" and the actual operation?

You should have a test case that does kind of the same thing as above, but with AES_CTX_COUNT threads.

@andresag01
Copy link
Author

@kjbracey-arm: Thanks for your input. Please note that I have created #5036 to add more stress tests like the one you are suggesting.

@adustm
Copy link
Member

adustm commented Nov 30, 2017

Hello @andresag01
I'm back on this topic eventually.
I've analysed your issue.
The problem is not the variety of contexts and the mix of them, the problem is only the 1st input that is empty and the test calls mbedtls_[sha1/sha256/md5]_finish without any call to mbedtls_[sha1/sha256/md5]_update ( the test goes from start to finish without _update).

The internal state machine of ST HAL code assumes that you've been through it even for an empty buffer.

I can easily fix that, in case any user wants to optimize its application and avoid calling _update in case of empty buffer.

My PR is ready, but I am not able to test MD5. It does not link.
Can you help me to make it link ?
I've created a mbedtls-config-changes.h that contains
#define MBEDTLS_MD5_C
I've created a mbed_app.json file with

{
    "macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls-config-changes.h\""]
}

I've added the test at the root of mbed-os and typed
mbed compile -m NUCLEO_F439ZI -t GCC_ARM -c -vv

I get the following link error

[DEBUG] Preproc: arm-none-eabi-cpp -E -P .\targets\TARGET_STM\TARGET_STM32F4\TARGET_STM32F439xI\device\TOOLCHAIN_GCC_ARM\STM32F439ZI.ld -Wl,--gc-sections -Wl,--wrap,main -Wl,--wrap
,_malloc_r -Wl,--wrap,_free_r -Wl,--wrap,_realloc_r -Wl,--wrap,_memalign_r -Wl,--wrap,_calloc_r -Wl,--wrap,exit -Wl,--wrap,atexit -Wl,-n -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -
mfloat-abi=softfp -o .\BUILD\NUCLEO_F439ZI\GCC_ARM\.link_script.ld
[DEBUG] Return: 0
[DEBUG] Link: arm-none-eabi-gcc @.\BUILD\NUCLEO_F439ZI\GCC_ARM\.link_files.txt
[DEBUG] Return: 1
[DEBUG] Errors: ./BUILD/NUCLEO_F439ZI/GCC_ARM/./main.o: In function `md5()':
[DEBUG] Errors: main.cpp:(.text._Z3md5v+0x28): undefined reference to `mbedtls_md5_init'
[DEBUG] Errors: main.cpp:(.text._Z3md5v+0x3a): undefined reference to `mbedtls_md5_starts'
[DEBUG] Errors: main.cpp:(.text._Z3md5v+0x92): undefined reference to `mbedtls_md5_update'
[DEBUG] Errors: main.cpp:(.text._Z3md5v+0xba): undefined reference to `mbedtls_md5_finish'
[DEBUG] Errors: main.cpp:(.text._Z3md5v+0xf0): undefined reference to `mbedtls_md5_free'
[DEBUG] Errors: collect2.exe: error: ld returned 1 exit status

How to enable MBEDTLS_MD5_C ?
Or you could test it directly from https://github.com/adustm/mbed/tree/fix5079_sha1_md5_sha256_hwcrypto

Kind regards
Armelle

@mazimkhan
Copy link

@adustm can you try un-commenting line https://github.com/ARMmbed/mbed-os/blob/master/features/mbedtls/inc/mbedtls/config.h#L2046
in file mbed-os/features/mbedtls/inc/mbedtls/config.h in your workspace.

@andresag01
Copy link
Author

Hi @adustm, my apologies for the delay in my reply. I am not sure if putting the application inside the mbed-os directory works. My understanding is that this directory should only contain the library code and tests, but the stress test that I wrote is written as if it was a user application. To test this, I normally just replace the code in the main.cpp of one of the applications at mbed-os-example-tls and then use it as normal. To illustrate this, I have done the setup for you in here in my fork which is ready to deploy your mbed-os fork and test the change with the normal mbed deploy && mbed compile -m NUCLEO_F439ZI -t GCC_ARM -c command.

After trying that I also found that the linking problem persists and tracked it down to a misplaced include in the file md5_alt.h. The following change fixes the problem as mbedtls/md5.h also includes mbedtls/config.h and that includes the device and example config files which defines MBEDTLS_MD5_C and MBEDTLS_MD5_ALT.

diff --git a/features/mbedtls/targets/TARGET_STM/md5_alt.c b/features/mbedtls/targets/TARGET_STM/md5_alt.c
index 328542b..63fb34b 100644
--- a/features/mbedtls/targets/TARGET_STM/md5_alt.c
+++ b/features/mbedtls/targets/TARGET_STM/md5_alt.c
@@ -17,9 +17,10 @@
  *  limitations under the License.
  *
  */
-#if defined(MBEDTLS_MD5_C)
 #include "mbedtls/md5.h"
 
+#if defined(MBEDTLS_MD5_C)
+
 #if defined(MBEDTLS_MD5_ALT)
 #include "mbedtls/platform.h"

I hope this helps, and once more, apologies for the delay to reply. Let me know if there are any further questions, but please note that I am currently not directly involved in the development of hardware acceleration APIs so it might take me a little time to reply.

@adustm
Copy link
Member

adustm commented Dec 14, 2017

Thanks @andresag01 . Moving #if defined(MBEDTLS_MD5_C) fixes my link problem. I push that in the PR

adustm added a commit to adustm/mbed that referenced this issue Jan 30, 2018
…if mbedtls_xxx_udate

was not called since mbedtls_xxx_start
cmonr added a commit that referenced this issue Jan 31, 2018
Fix #5079. Support of call to mbedtls_x_finish without calling mbedtls_x_update
adbridge pushed a commit that referenced this issue Feb 9, 2018
…tls_xxx_udate was not called since mbedtls_xxx_start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants