-
Notifications
You must be signed in to change notification settings - Fork 927
Add key generation for private encryption key #2559
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
Open
Wika-Group-IIoT-RD
wants to merge
1
commit into
mcu-tools:main
Choose a base branch
from
Wika-Group-IIoT-RD:feat/gen_enc_key_Zephyr_exp
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| /* | ||
| * Copyright (c) 2026 WIKA Alexander Wiegand SE & Co. KG | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
| #ifndef _BOOT_STORE_ENC_KEYS_H_ | ||
| #define _BOOT_STORE_ENC_KEYS_H_ | ||
|
|
||
| #include <stddef.h> | ||
| #include <stdbool.h> | ||
|
|
||
| /** | ||
| * @brief Store the private key into the flash partition | ||
| * | ||
| * @param key Pointer to the buffer where the key is stored | ||
| * @param key_len Size of the key | ||
| * | ||
| * @return 0 on success; nonzero on failure. | ||
| */ | ||
| int store_priv_enc_key(const unsigned char *key, size_t key_len); | ||
|
|
||
| /** | ||
| * @brief Check the private key encryption storage is empty. | ||
| * | ||
| * @retval true The key storage is empty. | ||
| * @retval false The key storage is not empty or the flash area could not be accessed. | ||
| * | ||
| **/ | ||
| bool is_key_storage_erased(); | ||
|
|
||
| #endif /*_BOOT_STORE_ENC_KEYS_H_*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /* | ||
| * Copyright (c) 2026 WIKA Alexander Wiegand SE & Co. KG | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
| #ifndef __GENERATE_KEY_PAIR_H__ | ||
| #define __GENERATE_KEY_PAIR_H__ | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| /** | ||
| * @brief Generate public and private key for encryption in (PKCS8 and PEM format). | ||
| * | ||
| * @return On failure, print error message. | ||
| * | ||
| */ | ||
| void generate_enc_key_pair(void); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif /* __GENERATE_KEY_PAIR_H__ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /* | ||
| * Copyright (c) 2026 WIKA Alexander Wiegand SE & Co. KG | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
| #include "mcuboot_config/mcuboot_config.h" | ||
|
|
||
| #if defined(MCUBOOT_GEN_ENC_KEY) | ||
| #include <bootutil/boot_store_enc_keys.h> | ||
| #include "bootutil_priv.h" | ||
| #include <bootutil/bootutil_macros.h> | ||
|
|
||
| #define PRIV_ENC_KEY_ALIGN_SIZE ALIGN_UP(MCUBOOT_PRIV_ENC_KEY_LEN, MCUBOOT_BOOT_MAX_ALIGN) | ||
|
|
||
| int | ||
| store_priv_enc_key(const unsigned char *key, size_t key_len) | ||
| { | ||
| if((key == NULL) || key_len != MCUBOOT_PRIV_ENC_KEY_LEN) | ||
| { | ||
| return -1; | ||
| } | ||
|
|
||
| const struct flash_area *fa; | ||
| int rc = flash_area_open(KEY_STORAGE_ID, &fa); | ||
| if (rc) | ||
| { | ||
| return rc; | ||
| } | ||
|
|
||
| uint32_t pad_off = ALIGN_UP(KEY_STORAGE_BASE, MCUBOOT_BOOT_MAX_ALIGN) - KEY_STORAGE_BASE; | ||
| uint8_t erased_val = flash_area_erased_val(fa); | ||
|
|
||
| rc = boot_erase_region(fa, pad_off, PRIV_ENC_KEY_ALIGN_SIZE, false); | ||
| if (rc != 0) { | ||
| return BOOT_EFLASH; | ||
| } | ||
|
|
||
| uint8_t priv_enc_key[PRIV_ENC_KEY_ALIGN_SIZE]; | ||
| memset(&priv_enc_key[0], erased_val, PRIV_ENC_KEY_ALIGN_SIZE); | ||
| memcpy(&priv_enc_key[0], key, MCUBOOT_PRIV_ENC_KEY_LEN); | ||
|
|
||
| rc = flash_area_write(fa, pad_off, &priv_enc_key[0], PRIV_ENC_KEY_ALIGN_SIZE); | ||
| flash_area_close(fa); | ||
| if (rc != 0) { | ||
| return BOOT_EFLASH; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| bool is_key_storage_erased(){ | ||
| const struct flash_area *fa; | ||
| if (flash_area_open(KEY_STORAGE_ID, &fa) < 0) | ||
| { | ||
| return false; | ||
| } | ||
| bool ret = bootutil_buffer_is_erased(fa, (const void*)ALIGN_UP(KEY_STORAGE_BASE, MCUBOOT_BOOT_MAX_ALIGN), MCUBOOT_PRIV_ENC_KEY_LEN); | ||
| flash_area_close(fa); | ||
| return ret; | ||
| } | ||
|
|
||
| #endif /* MCUBOOT_GEN_ENC_KEY */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| /* | ||
| * Copyright (c) 2026 WIKA Alexander Wiegand SE & Co. KG | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
| #include "mcuboot_config/mcuboot_config.h" | ||
|
|
||
| #if defined(MCUBOOT_GEN_ENC_KEY) | ||
| #include "mbedtls/entropy.h" | ||
| #include "mbedtls/ctr_drbg.h" | ||
| #include "mbedtls/pk.h" | ||
| #include "mbedtls/ecp.h" | ||
| #include "bootutil/generate_key_pair.h" | ||
| #include "bootutil/boot_store_enc_keys.h" | ||
| #include "pkcs8secp256write.h" | ||
| #include "bootutil/bootutil_log.h" | ||
| BOOT_LOG_MODULE_DECLARE(mcuboot); | ||
|
|
||
| #define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES) | ||
| #define PK_ECP_SIZE_BASE64 ((MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES*4+3-1)/3) | ||
| #define PEM_BEGIN_PUBLIC_KEY_SIZE 25 | ||
| #define PEM_END_PUBLIC_KEY_SIZE 27 | ||
| #define NEW_LINE_CHARS 3 | ||
| #define PEM_PUBLIC_KEY_SIZE (PEM_BEGIN_PUBLIC_KEY_SIZE + PK_ECP_SIZE_BASE64 + PEM_END_PUBLIC_KEY_SIZE + NEW_LINE_CHARS) | ||
|
|
||
| /** | ||
| * @brief Generate public and private key and contain in mbedtls_pk_context. | ||
| * | ||
| * @param pk Initialize mbedtls_pk_context and contains the generate key pair. | ||
| * | ||
| * @return 0 for Success. | ||
| * @return Not equal to zero, therefore failure. | ||
| */ | ||
| static int | ||
| gen_p256_keypair(mbedtls_pk_context *pk) | ||
| { | ||
| int ret; | ||
| mbedtls_entropy_context entropy; | ||
| mbedtls_ctr_drbg_context ctr_drbg; | ||
| const unsigned char pers[] = "keyge-p256-keygenkeyge-p256-keygen"; | ||
|
|
||
| mbedtls_pk_init(pk); | ||
| mbedtls_entropy_init(&entropy); | ||
| mbedtls_ctr_drbg_init(&ctr_drbg); | ||
|
|
||
| ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, | ||
| pers, sizeof(pers) - 1); | ||
| if (ret != 0) { | ||
| BOOT_LOG_ERR("SEED FAIL ret=%d", ret); | ||
| goto cleanup; | ||
| } | ||
|
|
||
| ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); | ||
| if (ret != 0) { | ||
| BOOT_LOG_ERR("PK_SETUP FAIL ret=%d", ret); | ||
| goto cleanup; | ||
| } | ||
|
|
||
| ret = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(*pk), | ||
| mbedtls_ctr_drbg_random, &ctr_drbg); | ||
| if (ret != 0) { | ||
| BOOT_LOG_ERR("GEN_KEY FAIL ret=%d", ret); | ||
| goto cleanup; | ||
| } | ||
|
|
||
| cleanup: | ||
| mbedtls_ctr_drbg_free(&ctr_drbg); | ||
| mbedtls_entropy_free(&entropy); | ||
| return ret; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Export private key in PKCS8 format. | ||
| * | ||
| * @param pk Initialize mbedtls_pk_context and contains the generate key pair. | ||
| * | ||
| * @return 0 for Success. | ||
| * @return Not equal to zero, therefore failure. | ||
| */ | ||
| static int | ||
| save_privkey_der(const mbedtls_pk_context *pk) | ||
| { | ||
| unsigned char buf[MCUBOOT_PRIV_ENC_KEY_LEN]; | ||
|
|
||
| int len = mbedtls_pk_write_keypkcs8_der(pk, buf, sizeof(buf)); | ||
| if (len != MCUBOOT_PRIV_ENC_KEY_LEN) { | ||
| BOOT_LOG_ERR("fails write pkcs8 der: len=%d", len); | ||
| return len; | ||
| } | ||
|
|
||
| int ret = store_priv_enc_key(buf, len); | ||
| if (ret != 0) | ||
| { | ||
| BOOT_LOG_ERR("key store fail store ret=%d",ret); | ||
| return ret; | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Export private and public key in PEM format. | ||
| * | ||
| * @param pk Initialize mbedtls_pk_context and contains the generate key pair. | ||
| * | ||
| * @return 0 for Success. | ||
| * @return Not equal to zero, therefore failure. | ||
| */ | ||
| static int | ||
| export_pub_pem(const mbedtls_pk_context *pk) | ||
| { | ||
| unsigned char buf_pub[PEM_PUBLIC_KEY_SIZE]; | ||
|
|
||
| int ret = mbedtls_pk_write_pubkey_pem(pk, buf_pub, sizeof(buf_pub)); | ||
| if (ret != 0) | ||
| { | ||
| BOOT_LOG_ERR("PUBKEY_PEM FAIL ret=%d", ret); | ||
| return ret; | ||
| } | ||
|
|
||
| BOOT_LOG_INF("\n%s", buf_pub); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| void | ||
| generate_enc_key_pair(void) | ||
| { | ||
| mbedtls_pk_context pk; | ||
| BOOT_LOG_INF("Generate enc key pair starting..."); | ||
|
|
||
| int ret = gen_p256_keypair(&pk); | ||
| if(ret != 0){ | ||
| BOOT_LOG_ERR("Error during the generation enc key pair"); | ||
| return; | ||
| } | ||
|
|
||
| ret = save_privkey_der(&pk); | ||
| if(ret != 0){ | ||
| BOOT_LOG_ERR("Error during safe of private key der"); | ||
| return; | ||
| } | ||
|
|
||
| BOOT_LOG_INF("Saved private enc key"); | ||
|
|
||
| ret = export_pub_pem(&pk); | ||
| if(ret != 0){ | ||
| BOOT_LOG_ERR("Error during the exportation of public key pem"); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| #endif /* MCUBOOT_GEN_ENC_KEY */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
|
|
||
| CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y | ||
|
|
||
| CONFIG_BOOT_GEN_ENC_KEY=y | ||
| CONFIG_BOOT_ENCRYPT_IMAGE=y | ||
|
|
||
| CONFIG_TEST_RANDOM_GENERATOR=y | ||
| CONFIG_TIMER_RANDOM_GENERATOR=y | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test random number generator is not appropriate for generating keys. It is dangerous to enable this even for an example, likewise with the timer. None of this code makes any sense without a true RNG source on the target.