Exemple #1
0
bootloader_sha256_handle_t bootloader_sha256_start()
{
    mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
    if (!ctx) {
        return NULL;
    }
    mbedtls_sha256_init(ctx);
    mbedtls_sha256_starts(ctx, false);
    return ctx;
}
/*
 * Compute SHA256 over the image.
 */
static int
bootutil_img_hash(struct image_header *hdr, const struct flash_area *fap,
                  uint8_t *tmp_buf, uint32_t tmp_buf_sz,
                  uint8_t *hash_result, uint8_t *seed, int seed_len)
{
    mbedtls_sha256_context sha256_ctx;
    uint32_t blk_sz;
    uint32_t size;
    uint32_t off;
    int rc;

    mbedtls_sha256_init(&sha256_ctx);
    mbedtls_sha256_starts(&sha256_ctx, 0);

    /* in some cases (split image) the hash is seeded with data from
     * the loader image */
    if(seed && (seed_len > 0)) {
        mbedtls_sha256_update(&sha256_ctx, seed, seed_len);
    }

    size = hdr->ih_img_size + hdr->ih_hdr_size;

    /*
     * Hash is computed over image header and image itself. No TLV is
     * included ATM.
     */
    size = hdr->ih_img_size + hdr->ih_hdr_size;
    for (off = 0; off < size; off += blk_sz) {
        /* Pet the watchdog, in case it is still enabled after a soft reset. */
        hal_watchdog_tickle();

        blk_sz = size - off;
        if (blk_sz > tmp_buf_sz) {
            blk_sz = tmp_buf_sz;
        }
        rc = flash_area_read(fap, off, tmp_buf, blk_sz);
        if (rc) {
            return rc;
        }
        mbedtls_sha256_update(&sha256_ctx, tmp_buf, blk_sz);
    }
    mbedtls_sha256_finish(&sha256_ctx, hash_result);

    return 0;
}
static void
boot_test_util_write_hash(const struct image_header *hdr, int slot)
{
    uint8_t tmpdata[1024];
    uint8_t hash[32];
    int rc;
    uint32_t off;
    uint32_t blk_sz;
    uint32_t sz;
    mbedtls_sha256_context ctx;
    uint8_t flash_id;
    uint32_t addr;
    struct image_tlv tlv;

    mbedtls_sha256_init(&ctx);
    mbedtls_sha256_starts(&ctx, 0);

    flash_id = boot_test_img_addrs[slot].flash_id;
    addr = boot_test_img_addrs[slot].address;

    sz = hdr->ih_hdr_size + hdr->ih_img_size;
    for (off = 0; off < sz; off += blk_sz) {
        blk_sz = sz - off;
        if (blk_sz > sizeof(tmpdata)) {
            blk_sz = sizeof(tmpdata);
        }
        rc = hal_flash_read(flash_id, addr + off, tmpdata, blk_sz);
        TEST_ASSERT(rc == 0);
        mbedtls_sha256_update(&ctx, tmpdata, blk_sz);
    }
    mbedtls_sha256_finish(&ctx, hash);

    tlv.it_type = IMAGE_TLV_SHA256;
    tlv._pad = 0;
    tlv.it_len = sizeof(hash);

    rc = hal_flash_write(flash_id, addr + off, &tlv, sizeof(tlv));
    TEST_ASSERT(rc == 0);
    off += sizeof(tlv);
    rc = hal_flash_write(flash_id, addr + off, hash, sizeof(hash));
    TEST_ASSERT(rc == 0);
}
/**
 * fast_sha256_vector - SHA256 hash for data vector
 * @num_elem: Number of elements in the data vector
 * @addr: Pointers to the data areas
 * @len: Lengths of the data blocks
 * @mac: Buffer for the hash
 * Returns: 0 on success, -1 of failure
 */
int 
fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len,
		  uint8_t *mac)
{
    mbedtls_sha256_context ctx;

    mbedtls_sha256_init(&ctx);

    mbedtls_sha256_starts(&ctx, 0);

    for(size_t index = 0; index < num_elem; index++) {
        mbedtls_sha256_update(&ctx, addr[index], len[index]);
    }

    mbedtls_sha256_finish(&ctx, mac);

    mbedtls_sha256_free(&ctx);

    return 0;
}
Exemple #5
0
void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
{
    memset( ctx, 0, sizeof(mbedtls_entropy_context) );

#if defined(MBEDTLS_THREADING_C)
    mbedtls_mutex_init( &ctx->mutex );
#endif

#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
    mbedtls_sha512_starts( &ctx->accumulator, 0 );
#else
    mbedtls_sha256_starts( &ctx->accumulator, 0 );
#endif
#if defined(MBEDTLS_HAVEGE_C)
    mbedtls_havege_init( &ctx->havege_data );
#endif

#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
    mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
                                MBEDTLS_ENTROPY_MIN_PLATFORM,
                                MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif
#if defined(MBEDTLS_TIMING_C)
    mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
                                MBEDTLS_ENTROPY_MIN_HARDCLOCK,
                                MBEDTLS_ENTROPY_SOURCE_WEAK );
#endif
#if defined(MBEDTLS_HAVEGE_C)
    mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data,
                                MBEDTLS_ENTROPY_MIN_HAVEGE,
                                MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
    mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
                                MBEDTLS_ENTROPY_MIN_HARDWARE,
                                MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
}
Exemple #6
0
static void sha256_starts_wrap( void *ctx )
{
    mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 0 );
}
Exemple #7
0
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
{
    int ret, count = 0, i, done;
    mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];

    if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );

#if defined(MBEDTLS_THREADING_C)
    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
        return( ret );
#endif

    /*
     * Always gather extra entropy before a call
     */
    do
    {
        if( count++ > ENTROPY_MAX_LOOP )
        {
            ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
            goto exit;
        }

        if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
            goto exit;

        done = 1;
        for( i = 0; i < ctx->source_count; i++ )
            if( ctx->source[i].size < ctx->source[i].threshold )
                done = 0;
    }
    while( ! done );

    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );

#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
    mbedtls_sha512_finish( &ctx->accumulator, buf );

    /*
     * Reset accumulator and counters and recycle existing entropy
     */
    memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) );
    mbedtls_sha512_starts( &ctx->accumulator, 0 );
    mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );

    /*
     * Perform second SHA-512 on entropy
     */
    mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
    mbedtls_sha256_finish( &ctx->accumulator, buf );

    /*
     * Reset accumulator and counters and recycle existing entropy
     */
    memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) );
    mbedtls_sha256_starts( &ctx->accumulator, 0 );
    mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );

    /*
     * Perform second SHA-256 on entropy
     */
    mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */

    for( i = 0; i < ctx->source_count; i++ )
        ctx->source[i].size = 0;

    memcpy( output, buf, len );

    ret = 0;

exit:
#if defined(MBEDTLS_THREADING_C)
    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif

    return( ret );
}
Exemple #8
0
int example(void)
{
    printf( "\r\n\r\n" );

    /*
     * Method 1: use all-in-one function of a specific SHA-xxx module
     */
    unsigned char output1[32]; /* SHA-256 outputs 32 bytes */

    /* 0 here means use the full SHA-256, not the SHA-224 variant */
    mbedtls_sha256(hello_buffer, hello_len, output1, 0);

    print_hex("Method 1", output1, sizeof output1);


    /*
     * Method 2: use the streaming interface of a specific SHA-xxx module
     * This is useful if we get our input piecewise.
     */
    unsigned char output2[32];
    mbedtls_sha256_context ctx2;

    mbedtls_sha256_init(&ctx2);
    mbedtls_sha256_starts(&ctx2, 0); /* SHA-256, not 224 */

    /* Simulating multiple fragments */
    mbedtls_sha256_update(&ctx2, hello_buffer, 1);
    mbedtls_sha256_update(&ctx2, hello_buffer + 1, 1);
    mbedtls_sha256_update(&ctx2, hello_buffer + 2, hello_len - 2);

    mbedtls_sha256_finish(&ctx2, output2);
    print_hex("Method 2", output2, sizeof output2);

    /* Or you could re-use the context by doing mbedtls_sha256_starts() again */
    mbedtls_sha256_free(&ctx2);

    /*
     * Method 3: use all-in-one function of the generice interface
     */
    unsigned char output3[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */

    /* Can easily pick any hash you want, by identifier */
    const mbedtls_md_info_t *md_info3 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);

    if (md_info3 == NULL)
    {
        printf("SHA256 not available\r\n");
        return 1;
    }

    int ret3 = mbedtls_md(md_info3, hello_buffer, hello_len, output3);

    if (ret3 != 0)
    {
        printf("md() returned -0x%04X\r\n", -ret3);
        return 1;
    }

    print_hex("Method 3", output3, mbedtls_md_get_size(md_info3));


    /*
     * Method 4: streaming & generic interface
     */
    unsigned char output4[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */

    const mbedtls_md_info_t *md_info4 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);

    if (md_info4 == NULL)
    {
        printf("SHA256 not available\r\n");
        return 1;
    }

    mbedtls_md_context_t ctx4;

    mbedtls_md_init(&ctx4);

    int ret4 = mbedtls_md_init_ctx(&ctx4, md_info4);
    if (ret4 != 0)
    {
        printf("md_init_ctx() returned -0x%04X\r\n", -ret4);
        return 1;
    }

    mbedtls_md_starts(&ctx4);

    /* Simulating multiple fragments */
    mbedtls_md_update(&ctx4, hello_buffer, 1);
    mbedtls_md_update(&ctx4, hello_buffer + 1, 1);
    mbedtls_md_update(&ctx4, hello_buffer + 2, hello_len - 2);

    mbedtls_md_finish(&ctx4, output4);
    print_hex("Method 4", output4, mbedtls_md_get_size(md_info4));

    /* Or you could re-use the context by doing mbedtls_md_starts() again */
    mbedtls_md_free(&ctx4);


    printf("\r\nDONE\r\n");

    return 0;
}
/*
 * Verify the integrity of the image.
 * Return non-zero if image could not be validated/does not validate.
 */
int
bootutil_img_validate(struct image_header *hdr, uint8_t flash_id, uint32_t addr,
  uint8_t *tmp_buf, uint32_t tmp_buf_sz)
{
    uint32_t blk_sz;
    uint32_t off;
    uint32_t size;
    mbedtls_sha256_context sha256_ctx;
    struct image_tlv tlv;
    uint8_t flash_hash[32];
    uint8_t computed_hash[32];
    int rc;

    if (hdr->ih_flags & IMAGE_F_HAS_SHA256) {
        /*
         * After image there's a TLV containing the hash.
         */
        mbedtls_sha256_init(&sha256_ctx);
        mbedtls_sha256_starts(&sha256_ctx, 0);

        /*
         * Hash is computed over image header and image itself. No TLV is
         * included ATM.
         */
        size = hdr->ih_img_size + hdr->ih_hdr_size;
        for (off = 0; off < size; off += blk_sz) {
            blk_sz = size - off;
            if (blk_sz > tmp_buf_sz) {
                blk_sz = tmp_buf_sz;
            }
            rc = hal_flash_read(flash_id, addr + off, tmp_buf, blk_sz);
            if (rc) {
                return rc;
            }
            mbedtls_sha256_update(&sha256_ctx, tmp_buf, blk_sz);
        }
        mbedtls_sha256_finish(&sha256_ctx, computed_hash);

        /*
         * Then find the hash TLV and this should match.
         */
        size += hdr->ih_tlv_size;
        for (; off < size; off += sizeof(tlv) + tlv.it_len) {
            rc = hal_flash_read(flash_id, addr + off, &tlv, sizeof(tlv));
            if (rc) {
                return rc;
            }
            if (tlv.it_type == IMAGE_TLV_SHA256) {
                if (tlv.it_len != sizeof(flash_hash)) {
                    return -1;
                }
                rc = hal_flash_read(flash_id, addr + off + sizeof(tlv),
                  flash_hash, sizeof(flash_hash));
                if (rc) {
                    return rc;
                }
                if (memcmp(flash_hash, computed_hash, sizeof(flash_hash))) {
                    return -1;
                }
                return 0;
            }
        }
        /*
         * Header said there should hash TLV, no TLV found.
         */
        return -1;
    }
    return -1;
}