static void *sha224_ctx_alloc( void ) { void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); if( ctx != NULL ) mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); return( ctx ); }
void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) { ctx->source_count = 0; memset( ctx->source, 0, sizeof( ctx->source ) ); #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_init( &ctx->mutex ); #endif ctx->accumulator_started = 0; #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) mbedtls_sha512_init( &ctx->accumulator ); #else mbedtls_sha256_init( &ctx->accumulator ); #endif #if defined(MBEDTLS_HAVEGE_C) mbedtls_havege_init( &ctx->havege_data ); #endif /* Reminder: Update ENTROPY_HAVE_STRONG in the test files * when adding more strong entropy sources here. */ #if defined(MBEDTLS_TEST_NULL_ENTROPY) mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, 1, MBEDTLS_ENTROPY_SOURCE_STRONG ); #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 #if defined(MBEDTLS_ENTROPY_NV_SEED) mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, MBEDTLS_ENTROPY_BLOCK_SIZE, MBEDTLS_ENTROPY_SOURCE_STRONG ); ctx->initial_entropy_run = 0; #endif #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ }
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; }
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; }
int crypto_hash_sha256_init(crypto_hash_sha256_state *state) { mbedtls_sha256_init(state); return 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_ENTROPY_NV_SEED) /* Update the NV entropy seed before generating any entropy for outside * use. */ if( ctx->initial_entropy_run == 0 ) { ctx->initial_entropy_run = 1; if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) return( ret ); } #endif #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) /* * Note that at this stage it is assumed that the accumulator was started * in a previous call to entropy_update(). If this is not guaranteed, the * code below will fail. */ if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 ) goto exit; /* * Reset accumulator and counters and recycle existing entropy */ mbedtls_sha512_free( &ctx->accumulator ); mbedtls_sha512_init( &ctx->accumulator ); if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) goto exit; if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) goto exit; /* * Perform second SHA-512 on entropy */ if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ) ) != 0 ) goto exit; #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 ) goto exit; /* * Reset accumulator and counters and recycle existing entropy */ mbedtls_sha256_free( &ctx->accumulator ); mbedtls_sha256_init( &ctx->accumulator ); if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) goto exit; if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) goto exit; /* * Perform second SHA-256 on entropy */ if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ) ) != 0 ) goto exit; #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: mbedtls_zeroize( buf, sizeof( buf ) ); #if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif return( ret ); }