Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 33 additions & 32 deletions boot/bootutil/src/encrypted.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
#include "bootutil/crypto/aes_kw.h"
#endif

#if !defined(MCUBOOT_USE_PSA_CRYPTO)
#if defined(MCUBOOT_ENCRYPT_EC256)
#include "bootutil/crypto/ecdh_p256.h"
#endif

#if !defined(MCUBOOT_USE_PSA_CRYPTO)
#if defined(MCUBOOT_ENCRYPT_X25519)
#include "bootutil/crypto/ecdh_x25519.h"
#endif
Expand All @@ -50,7 +50,7 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
#include "bootutil_priv.h"

/* NOUP Fixme: */
#if !defined(CONFIG_BOOT_ED25519_PSA)
#if !defined(CONFIG_BOOT_ED25519_PSA) && !defined(CONFIG_BOOT_ECDSA_PSA)
#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
#if defined(_compare)
static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
Expand Down Expand Up @@ -105,65 +105,64 @@ static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
* curve keypair. See RFC5208 and RFC5915.
*/
static int
parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
parse_priv_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
{
int rc;
size_t len;
int version;
mbedtls_asn1_buf alg;
mbedtls_asn1_buf param;

if ((rc = mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
if (mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return -1;
}

if (*p + len != end) {
return -2;
return -1;
}

version = 0;
if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
return -3;
return -1;
}

if ((rc = mbedtls_asn1_get_alg(p, end, &alg, &param)) != 0) {
return -5;
if (mbedtls_asn1_get_alg(p, end, &alg, &param) != 0) {
return -1;
}

if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
return -6;
return -1;
}
if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 ||
memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
return -7;
return -1;
}

if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
return -8;
if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return -1;
}

/* RFC5915 - ECPrivateKey */

if ((rc = mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return -9;
if (mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return -1;
}

version = 0;
if (mbedtls_asn1_get_int(p, end, &version) || version != 1) {
return -10;
return -1;
}

/* privateKey */

if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
return -11;
if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return -1;
}

if (len != NUM_ECC_BYTES) {
return -12;
return -1;
}

memcpy(private_key, *p, len);
Expand All @@ -180,7 +179,7 @@ static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_ORG_GOV X25519_OID;

static int
parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
parse_priv_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
{
size_t len;
int version;
Expand All @@ -193,33 +192,33 @@ parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
}

if (*p + len != end) {
return -2;
return -1;
}

version = 0;
if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
return -3;
return -1;
}

if (mbedtls_asn1_get_alg(p, end, &alg, &param) != 0) {
return -4;
return -1;
}

if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
return -5;
return -1;
}

if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return -6;
return -1;
}

if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return -7;
return -1;
}

if (len != EC_PRIVK_LEN) {
return -8;
return -1;
}

memcpy(private_key, *p, EC_PRIVK_LEN);
Expand Down Expand Up @@ -455,8 +454,9 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)
* Load the stored EC256 decryption private key
*/

rc = parse_ec256_enckey(&cp, cpend, private_key);
rc = parse_priv_enckey(&cp, cpend, private_key);
if (rc) {
BOOT_LOG_ERR("Failed to parse ASN1 private key");
return rc;
}

Expand All @@ -482,8 +482,9 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)
* Load the stored X25519 decryption private key
*/

rc = parse_x25519_enckey(&cp, cpend, private_key);
rc = parse_priv_enckey(&cp, cpend, private_key);
if (rc) {
BOOT_LOG_ERR("Failed to parse ASN1 private key");
return rc;
}

Expand Down Expand Up @@ -580,7 +581,7 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)

return rc;
}
#endif /* CONFIG_BOOT_ED25519_PSA */
#endif /* CONFIG_BOOT_ED25519_PSA && CONFIG_BOOT_ECDSA_PSA */

/*
* Load encryption key.
Expand Down
96 changes: 92 additions & 4 deletions boot/bootutil/src/encrypted_psa.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,18 @@ BOOT_LOG_MODULE_DECLARE(mcuboot_psa_enc);
#define PSA_HMAC_HKDF_SHA PSA_ALG_SHA_256
#endif

#if defined(MCUBOOT_ENCRYPT_EC256)
#define NUM_ECC_BYTES (256 / 8)
static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
#define ECC_FAMILY PSA_ECC_FAMILY_SECP_R1
#endif /* defined(MCUBOOT_ENCRYPT_EC256) */
#if defined(MCUBOOT_ENCRYPT_X25519)
#define X25519_OID "\x6e"
static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_ORG_GOV X25519_OID;
#define ECC_FAMILY PSA_ECC_FAMILY_MONTGOMERY
#endif /* defined(MCUBOOT_ENCRYPT_X25519) */

/* Partitioning of HKDF derived material, from the exchange derived key */
/* AES key encryption key */
Expand All @@ -51,9 +60,86 @@ static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \
/* Total size */
#define HKDF_SIZE (HKDF_AES_KEY_SIZE + HKDF_MAC_FEED_SIZE)

#if defined(MCUBOOT_ENCRYPT_EC256)
/* Fixme: This duplicates code from encrypted.c and depends on mbedtls */

/*
* Parses the output of `imgtool keygen`, which produces a PKCS#8 elliptic
* curve keypair. See RFC5208 and RFC5915.
*/
static int
parse_priv_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
{
size_t len;
int version;
mbedtls_asn1_buf alg;
mbedtls_asn1_buf param;

if (mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return -1;
}

if (*p + len != end) {
return -1;
}

version = 0;
if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
return -1;
}

if (mbedtls_asn1_get_alg(p, end, &alg, &param) != 0) {
return -1;
}

if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
return -1;
}
if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 ||
memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
return -1;
}

if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return -1;
}

/* RFC5915 - ECPrivateKey */

if (mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return -1;
}

version = 0;
if (mbedtls_asn1_get_int(p, end, &version) || version != 1) {
return -1;
}

/* privateKey */

if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return -1;
}

if (len != NUM_ECC_BYTES) {
return -1;
}

memcpy(private_key, *p, len);

/* publicKey usually follows but is not parsed here */

return 0;
}
#endif /* defined(MCUBOOT_ENCRYPT_EC256) */

#if defined(MCUBOOT_ENCRYPT_X25519)
/* Fixme: This duplicates code from encrypted.c and depends on mbedtls */
static int
parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
parse_priv_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
{
size_t len;
int version;
Expand Down Expand Up @@ -98,6 +184,7 @@ parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
memcpy(private_key, *p, EC_PRIVK_LEN);
return 0;
}
#endif /* defined(MCUBOOT_ENCRYPT_X25519) */

void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
{
Expand Down Expand Up @@ -153,14 +240,15 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)
}

/*
* Load the stored X25519 decryption private key
* * Load the stored decryption private key
*/
rc = parse_x25519_enckey(&cp, cpend, private_key);
rc = parse_priv_enckey(&cp, cpend, private_key);
if (rc) {
BOOT_LOG_ERR("Failed to parse ASN1 private key");
return rc;
}

psa_set_key_type(&kattr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY));
psa_set_key_type(&kattr, PSA_KEY_TYPE_ECC_KEY_PAIR(ECC_FAMILY));
psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DERIVE);
psa_set_key_algorithm(&kattr, PSA_ALG_ECDH);

Expand Down
9 changes: 5 additions & 4 deletions boot/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,12 @@ zephyr_library_sources(
${BOOT_DIR}/bootutil/src/fault_injection_hardening.c
)

if(DEFINED CONFIG_BOOT_ENCRYPT_X25519 AND DEFINED CONFIG_BOOT_ED25519_PSA)
if((CONFIG_BOOT_ENCRYPT_X25519 AND CONFIG_BOOT_ED25519_PSA)
OR (CONFIG_BOOT_ENCRYPT_EC256 AND CONFIG_BOOT_ECDSA_PSA))
zephyr_library_sources(${BOOT_DIR}/bootutil/src/encrypted_psa.c)
endif()

if(DEFINED CONFIG_MEASURED_BOOT OR DEFINED CONFIG_BOOT_SHARE_DATA)
if(CONFIG_MEASURED_BOOT OR CONFIG_BOOT_SHARE_DATA)
zephyr_library_sources(
${BOOT_DIR}/bootutil/src/boot_record.c
)
Expand Down Expand Up @@ -321,7 +322,7 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519)
endif()
endif()

if(NOT CONFIG_BOOT_ED25519_PSA)
if(NOT CONFIG_BOOT_ED25519_PSA AND NOT CONFIG_BOOT_ECDSA_PSA)
if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519)
zephyr_library_sources(
${TINYCRYPT_DIR}/source/aes_encrypt.c
Expand All @@ -333,7 +334,7 @@ if(NOT CONFIG_BOOT_ED25519_PSA)
endif()
endif()

if(CONFIG_BOOT_ENCRYPT_EC256)
if(CONFIG_BOOT_ENCRYPT_EC256 AND NOT CONFIG_BOOT_ECDSA_PSA)
zephyr_library_sources(
${TINYCRYPT_DIR}/source/ecc_dh.c
)
Expand Down