/* * Copyright (c) 2017-2021 Nordic Semiconductor ASA * Copyright (c) 2015 Runtime Inc * Copyright (c) 2017 Linaro Ltd * Copyright (c) 2020 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include "flash_map_priv.h" #include #include #define SHA256_DIGEST_SIZE 32 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) #include #define SUCCESS_VALUE PSA_SUCCESS #else #include #define SUCCESS_VALUE 0 #endif int flash_area_check_int_sha256(const struct flash_area *fa, const struct flash_area_check *fac) { unsigned char hash[SHA256_DIGEST_SIZE]; #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) psa_hash_operation_t hash_ctx; #else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ mbedtls_sha256_context hash_ctx; #endif int to_read; int pos; int rc; if (fa == NULL || fac == NULL || fac->match == NULL || fac->rbuf == NULL || fac->clen == 0 || fac->rblen == 0) { return -EINVAL; } if (!is_in_flash_area_bounds(fa, fac->off, fac->clen)) { return -EINVAL; } #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) hash_ctx = psa_hash_operation_init(); rc = psa_hash_setup(&hash_ctx, PSA_ALG_SHA_256); #else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ mbedtls_sha256_init(&hash_ctx); rc = mbedtls_sha256_starts(&hash_ctx, false); #endif if (rc != SUCCESS_VALUE) { return -ESRCH; } to_read = fac->rblen; for (pos = 0; pos < fac->clen; pos += to_read) { if (pos + to_read > fac->clen) { to_read = fac->clen - pos; } rc = flash_read(fa->fa_dev, (fa->fa_off + fac->off + pos), fac->rbuf, to_read); if (rc != 0) { goto error; } #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) rc = psa_hash_update(&hash_ctx, fac->rbuf, to_read); #else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ rc = mbedtls_sha256_update(&hash_ctx, fac->rbuf, to_read); #endif if (rc != SUCCESS_VALUE) { rc = -ESRCH; goto error; } } #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) size_t hash_len; rc = psa_hash_finish(&hash_ctx, hash, sizeof(hash), &hash_len); #else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ rc = mbedtls_sha256_finish(&hash_ctx, hash); #endif if (rc != SUCCESS_VALUE) { rc = -ESRCH; goto error; } if (memcmp(hash, fac->match, SHA256_DIGEST_SIZE)) { #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) /* The operation has already been terminated. */ return -EILSEQ; #else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ rc = -EILSEQ; goto error; #endif } error: #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) psa_hash_abort(&hash_ctx); #else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ mbedtls_sha256_free(&hash_ctx); #endif return rc; }