Merge pull request #17 from MacDue/encrypted_img_fixes
Some fixes/enhancements for esp_encrypted_img
This commit is contained in:
commit
6ce72eb948
|
@ -72,12 +72,10 @@ jobs:
|
|||
idf_target: esp32s3 # ESP32S3 support started with version 4.4
|
||||
runs-on: [self-hosted, linux, docker, esp32] # Unfortunately `${{ matrix.idf_target }}` is not accepted here
|
||||
container:
|
||||
image: python:3.7-slim-buster
|
||||
image: python:3.7-buster
|
||||
options: --privileged # Privileged mode has access to serial ports
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: test_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
|
||||
|
|
|
@ -8,8 +8,6 @@ jobs:
|
|||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: pre-commit/action@v2.0.3
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: "1.0.2"
|
||||
version: "2.0.0"
|
||||
description: ESP Encrypted Image Abstraction Layer
|
||||
url: https://github.com/espressif/idf-extra-components/tree/master/esp_encrypted_img
|
||||
dependencies:
|
||||
|
|
|
@ -86,7 +86,7 @@ esp_decrypt_handle_t esp_encrypted_img_decrypt_start(const esp_decrypt_cfg_t *cf
|
|||
* - ESP_ERR_DECRYPT_IN_PROGRESS Decryption is in process
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decrypt_arg_t *args);
|
||||
esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t ctx, pre_enc_decrypt_arg_t *args);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -98,7 +98,7 @@ esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decr
|
|||
* - ESP_FAIL On failure
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t esp_encrypted_img_decrypt_end(esp_decrypt_handle_t *ctx);
|
||||
esp_err_t esp_encrypted_img_decrypt_end(esp_decrypt_handle_t ctx);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -29,20 +29,6 @@ typedef enum {
|
|||
ESP_PRE_ENC_DATA_DECODE_STATE,
|
||||
} esp_encrypted_img_state;
|
||||
|
||||
struct esp_encrypted_img_handle {
|
||||
const char *rsa_pem;
|
||||
size_t rsa_len;
|
||||
uint32_t binary_file_len;
|
||||
uint32_t binary_file_read;
|
||||
char *gcm_key;
|
||||
char *iv;
|
||||
char auth_tag[16];
|
||||
esp_encrypted_img_state state;
|
||||
mbedtls_gcm_context gcm_ctx;
|
||||
size_t cache_buf_len;
|
||||
char *cache_buf;
|
||||
};
|
||||
|
||||
#define GCM_KEY_SIZE 32
|
||||
#define MAGIC_SIZE 4
|
||||
#define ENC_GCM_KEY_SIZE 384
|
||||
|
@ -51,6 +37,20 @@ struct esp_encrypted_img_handle {
|
|||
#define AUTH_SIZE 16
|
||||
#define RESERVED_HEADER 88
|
||||
|
||||
struct esp_encrypted_img_handle {
|
||||
char *rsa_pem;
|
||||
size_t rsa_len;
|
||||
uint32_t binary_file_len;
|
||||
uint32_t binary_file_read;
|
||||
char gcm_key[GCM_KEY_SIZE];
|
||||
char iv[IV_SIZE];
|
||||
char auth_tag[AUTH_SIZE];
|
||||
esp_encrypted_img_state state;
|
||||
mbedtls_gcm_context gcm_ctx;
|
||||
size_t cache_buf_len;
|
||||
char *cache_buf;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char magic[MAGIC_SIZE];
|
||||
char enc_gcm[ENC_GCM_KEY_SIZE];
|
||||
|
@ -69,10 +69,6 @@ typedef struct esp_encrypted_img_handle esp_encrypted_img_t;
|
|||
static int decipher_gcm_key(char *enc_gcm, esp_encrypted_img_t *handle)
|
||||
{
|
||||
int ret = 1;
|
||||
handle->gcm_key = calloc(1, GCM_KEY_SIZE);
|
||||
if (!handle->gcm_key) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
size_t olen = 0;
|
||||
mbedtls_pk_context pk;
|
||||
mbedtls_entropy_context entropy;
|
||||
|
@ -87,7 +83,6 @@ static int decipher_gcm_key(char *enc_gcm, esp_encrypted_img_t *handle)
|
|||
&entropy, (const unsigned char *) pers,
|
||||
strlen(pers))) != 0) {
|
||||
ESP_LOGE(TAG, "failed\n ! mbedtls_ctr_drbg_seed returned -0x%04x\n", (unsigned int) - ret);
|
||||
free(handle->gcm_key);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -99,14 +94,12 @@ static int decipher_gcm_key(char *enc_gcm, esp_encrypted_img_t *handle)
|
|||
if ( (ret = mbedtls_pk_parse_key(&pk, (const unsigned char *) handle->rsa_pem, handle->rsa_len, NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
|
||||
#endif
|
||||
ESP_LOGE(TAG, "failed\n ! mbedtls_pk_parse_keyfile returned -0x%04x\n", (unsigned int) - ret );
|
||||
free(handle->gcm_key);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (( ret = mbedtls_pk_decrypt( &pk, (const unsigned char *)enc_gcm, ENC_GCM_KEY_SIZE, (unsigned char *)handle->gcm_key, &olen, GCM_KEY_SIZE,
|
||||
mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) {
|
||||
ESP_LOGE(TAG, "failed\n ! mbedtls_pk_decrypt returned -0x%04x\n", (unsigned int) - ret );
|
||||
free(handle->gcm_key);
|
||||
goto exit;
|
||||
}
|
||||
handle->cache_buf = realloc(handle->cache_buf, 16);
|
||||
|
@ -116,16 +109,12 @@ static int decipher_gcm_key(char *enc_gcm, esp_encrypted_img_t *handle)
|
|||
handle->state = ESP_PRE_ENC_IMG_READ_IV;
|
||||
handle->binary_file_read = 0;
|
||||
handle->cache_buf_len = 0;
|
||||
handle->iv = calloc(1, IV_SIZE);
|
||||
if (!handle->iv) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_pk_free( &pk );
|
||||
mbedtls_entropy_free( &entropy );
|
||||
mbedtls_ctr_drbg_free( &ctr_drbg );
|
||||
free((void *)handle->rsa_pem);
|
||||
free(handle->rsa_pem);
|
||||
handle->rsa_pem = NULL;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
@ -156,21 +145,16 @@ esp_decrypt_handle_t esp_encrypted_img_decrypt_start(const esp_decrypt_cfg_t *cf
|
|||
goto failure;
|
||||
}
|
||||
|
||||
memcpy((void *)handle->rsa_pem, cfg->rsa_pub_key, cfg->rsa_pub_key_len);
|
||||
memcpy(handle->rsa_pem, cfg->rsa_pub_key, cfg->rsa_pub_key_len);
|
||||
handle->rsa_len = cfg->rsa_pub_key_len;
|
||||
handle->state = ESP_PRE_ENC_IMG_READ_MAGIC;
|
||||
|
||||
esp_decrypt_handle_t *ctx = (esp_decrypt_handle_t *)handle;
|
||||
esp_decrypt_handle_t ctx = (esp_decrypt_handle_t)handle;
|
||||
return ctx;
|
||||
|
||||
failure:
|
||||
if (!handle) {
|
||||
return NULL;
|
||||
}
|
||||
if (handle->rsa_pem) {
|
||||
free((void *)handle->rsa_pem);
|
||||
}
|
||||
if (handle) {
|
||||
free(handle->rsa_pem);
|
||||
free(handle);
|
||||
}
|
||||
return NULL;
|
||||
|
@ -280,7 +264,7 @@ static void read_and_cache_data(esp_encrypted_img_t *handle, pre_enc_decrypt_arg
|
|||
handle->binary_file_read += MIN(args->data_in_len - temp, data_left);
|
||||
}
|
||||
|
||||
esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decrypt_arg_t *args)
|
||||
esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t ctx, pre_enc_decrypt_arg_t *args)
|
||||
{
|
||||
if (ctx == NULL || args == NULL || args->data_in == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
@ -301,7 +285,8 @@ esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decr
|
|||
|
||||
if (recv_magic != esp_enc_img_magic) {
|
||||
ESP_LOGE(TAG, "Magic Verification failed");
|
||||
free((void *)handle->rsa_pem);
|
||||
free(handle->rsa_pem);
|
||||
handle->rsa_pem = NULL;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
curr_index += MAGIC_SIZE;
|
||||
|
@ -312,7 +297,8 @@ esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decr
|
|||
|
||||
if (recv_magic != esp_enc_img_magic) {
|
||||
ESP_LOGE(TAG, "Magic Verification failed");
|
||||
free((void *)handle->rsa_pem);
|
||||
free(handle->rsa_pem);
|
||||
handle->rsa_pem = NULL;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
handle->binary_file_read = 0;
|
||||
|
@ -360,7 +346,6 @@ esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decr
|
|||
ESP_LOGE(TAG, "Error: mbedtls_gcm_set_key: -0x%04x\n", (unsigned int) - err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(handle->gcm_key);
|
||||
#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
|
||||
if (mbedtls_gcm_starts(&handle->gcm_ctx, MBEDTLS_GCM_DECRYPT, (const unsigned char *)handle->iv, IV_SIZE, NULL, 0) != 0) {
|
||||
#else
|
||||
|
@ -369,8 +354,6 @@ esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decr
|
|||
ESP_LOGE(TAG, "Error: mbedtls_gcm_starts: -0x%04x\n", (unsigned int) - err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(handle->iv);
|
||||
handle->iv = NULL;
|
||||
} else {
|
||||
return ESP_ERR_NOT_FINISHED;
|
||||
}
|
||||
|
@ -427,7 +410,7 @@ esp_err_t esp_encrypted_img_decrypt_data(esp_decrypt_handle_t *ctx, pre_enc_decr
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_encrypted_img_decrypt_end(esp_decrypt_handle_t *ctx)
|
||||
esp_err_t esp_encrypted_img_decrypt_end(esp_decrypt_handle_t ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
@ -445,37 +428,29 @@ esp_err_t esp_encrypted_img_decrypt_end(esp_decrypt_handle_t *ctx)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
char *got_auth = calloc(1, AUTH_SIZE);
|
||||
if (!got_auth) {
|
||||
ESP_LOGE(TAG, "Unable to allocate memory");
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
unsigned char got_auth[AUTH_SIZE] = {0};
|
||||
#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
|
||||
err = mbedtls_gcm_finish(&handle->gcm_ctx, (unsigned char *)got_auth, AUTH_SIZE);
|
||||
err = mbedtls_gcm_finish(&handle->gcm_ctx, got_auth, AUTH_SIZE);
|
||||
#else
|
||||
size_t olen;
|
||||
err = mbedtls_gcm_finish(&handle->gcm_ctx, NULL, 0, &olen, (unsigned char *)got_auth, AUTH_SIZE);
|
||||
err = mbedtls_gcm_finish(&handle->gcm_ctx, NULL, 0, &olen, got_auth, AUTH_SIZE);
|
||||
#endif
|
||||
if (err != 0) {
|
||||
ESP_LOGE(TAG, "Error: %d", err);
|
||||
free(got_auth);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
if (memcmp(got_auth, handle->auth_tag, AUTH_SIZE) != 0) {
|
||||
ESP_LOGE(TAG, "Invalid Auth");
|
||||
free(got_auth);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
free(got_auth);
|
||||
}
|
||||
err = ESP_OK;
|
||||
exit:
|
||||
mbedtls_gcm_free(&handle->gcm_ctx);
|
||||
free(handle->cache_buf);
|
||||
free(handle->rsa_pem);
|
||||
free(handle);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -4,8 +4,14 @@
|
|||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
|
||||
#include "unity.h"
|
||||
#if __has_include("esp_random.h")
|
||||
#include "esp_random.h"
|
||||
#else
|
||||
#include "esp_system.h"
|
||||
#endif
|
||||
#include "esp_encrypted_img.h"
|
||||
|
||||
extern const uint8_t rsa_private_pem_start[] asm("_binary_test_rsa_private_key_pem_start");
|
||||
|
@ -20,7 +26,7 @@ TEST_CASE("Sending all data at once", "[encrypted_img]")
|
|||
.rsa_pub_key = (char *)rsa_private_pem_start,
|
||||
.rsa_pub_key_len = rsa_private_pem_end - rsa_private_pem_start,
|
||||
};
|
||||
esp_decrypt_handle_t *ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
esp_decrypt_handle_t ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
|
||||
pre_enc_decrypt_arg_t *args = calloc(1, sizeof(pre_enc_decrypt_arg_t));
|
||||
|
@ -50,7 +56,7 @@ TEST_CASE("Sending 1 byte data at once", "[encrypted_img]")
|
|||
.rsa_pub_key = (char *)rsa_private_pem_start,
|
||||
.rsa_pub_key_len = rsa_private_pem_end - rsa_private_pem_start,
|
||||
};
|
||||
esp_decrypt_handle_t *ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
esp_decrypt_handle_t ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
|
||||
pre_enc_decrypt_arg_t *args = calloc(1, sizeof(pre_enc_decrypt_arg_t));
|
||||
|
@ -151,7 +157,7 @@ TEST_CASE("Invalid Magic", "[encrypted_img]")
|
|||
.rsa_pub_key = (char *)rsa_private_pem_start,
|
||||
.rsa_pub_key_len = rsa_private_pem_end - rsa_private_pem_start,
|
||||
};
|
||||
esp_decrypt_handle_t *ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
esp_decrypt_handle_t ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
|
||||
pre_enc_decrypt_arg_t *args = calloc(1, sizeof(pre_enc_decrypt_arg_t));
|
||||
|
@ -244,7 +250,7 @@ TEST_CASE("Invalid Image", "[encrypted_img]")
|
|||
.rsa_pub_key = (char *)rsa_private_pem_start,
|
||||
.rsa_pub_key_len = rsa_private_pem_end - rsa_private_pem_start,
|
||||
};
|
||||
esp_decrypt_handle_t *ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
esp_decrypt_handle_t ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
|
||||
pre_enc_decrypt_arg_t *args = calloc(1, sizeof(pre_enc_decrypt_arg_t));
|
||||
|
@ -272,7 +278,7 @@ TEST_CASE("Sending random size data at once", "[encrypted_img]")
|
|||
.rsa_pub_key = (char *)rsa_private_pem_start,
|
||||
.rsa_pub_key_len = rsa_private_pem_end - rsa_private_pem_start,
|
||||
};
|
||||
esp_decrypt_handle_t *ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
esp_decrypt_handle_t ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
|
||||
pre_enc_decrypt_arg_t *args = calloc(1, sizeof(pre_enc_decrypt_arg_t));
|
||||
|
@ -304,3 +310,20 @@ TEST_CASE("Sending random size data at once", "[encrypted_img]")
|
|||
}
|
||||
free(args);
|
||||
}
|
||||
|
||||
TEST_CASE("Test canceling decryption frees memory", "[encrypted_img]")
|
||||
{
|
||||
esp_decrypt_cfg_t cfg = {
|
||||
.rsa_pub_key = (char *)rsa_private_pem_start,
|
||||
.rsa_pub_key_len = rsa_private_pem_end - rsa_private_pem_start,
|
||||
};
|
||||
int free_bytes_start = xPortGetFreeHeapSize();
|
||||
esp_decrypt_handle_t ctx = esp_encrypted_img_decrypt_start(&cfg);
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
|
||||
(void) esp_encrypted_img_decrypt_end(ctx);
|
||||
int free_bytes_end = xPortGetFreeHeapSize();
|
||||
|
||||
// +/- 16 bytes to allow for some small fluctuations
|
||||
TEST_ASSERT(abs(free_bytes_start - free_bytes_end) <= 16);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ def encrypt(input_file: str, rsa_key_file_name: str, output_file: str) -> None:
|
|||
encrypted_gcm_key = public_key.encrypt(gcm_key, padding.PKCS1v15())
|
||||
ciphertext, authtag = encrypt_binary(data, gcm_key, iv)
|
||||
|
||||
with open(output_file, 'ab') as image:
|
||||
with open(output_file, 'wb') as image:
|
||||
image.write(esp_enc_img_magic.to_bytes(MAGIC_SIZE, 'little'))
|
||||
image.write((encrypted_gcm_key))
|
||||
image.write((iv))
|
||||
|
@ -98,7 +98,7 @@ def decrypt(input_file: str, rsa_key: str, output_file: str) -> None:
|
|||
|
||||
decrypted_binary = decrypt_binary(enc_bin, auth, gcm_key, iv)
|
||||
|
||||
with open(output_file, 'ab') as file:
|
||||
with open(output_file, 'wb') as file:
|
||||
file.write(decrypted_binary)
|
||||
print('Done')
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 4f5e89fa84ce1d178a6765b8b46f2b6f91216677
|
||||
Subproject commit f0ad119206032b39790fa2882d666443fc7481b7
|
|
@ -3,8 +3,13 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "randombytes_internal.h"
|
||||
#include "sdkconfig.h"
|
||||
#if __has_include("esp_random.h")
|
||||
#include "esp_random.h"
|
||||
#else
|
||||
#include "esp_system.h"
|
||||
#endif
|
||||
#include "randombytes_internal.h"
|
||||
|
||||
static const char *randombytes_esp32xx_implementation_name(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue