diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index ef997105ba..e31d0352e9 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -142,10 +142,14 @@ ASSERTION_LEVELS = { "SILENT": "CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT", } +SIGNING_SCHEME_RSA3072 = "rsa3072" +SIGNING_SCHEME_ECDSA256 = "ecdsa256" +SIGNING_SCHEME_ECDSA_V1 = "ecdsa_v1" + SIGNING_SCHEMES = { - "rsa3072": "CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME", - "ecdsa256": "CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME", - "ecdsa_v1": "CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME", + SIGNING_SCHEME_RSA3072: "CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME", + SIGNING_SCHEME_ECDSA256: "CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME", + SIGNING_SCHEME_ECDSA_V1: "CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME", } # A Secure Boot v2 image carries at most three signature blocks, and hardware @@ -1263,7 +1267,7 @@ _SIGNED_OTA_VERIFICATION_SCHEMA = cv.Schema( cv.ensure_list(_validate_trusted_key), cv.Length(min=1, max=SIGNED_OTA_MAX_KEYS), ), - cv.Optional(CONF_SIGNING_SCHEME, default="rsa3072"): cv.one_of( + cv.Optional(CONF_SIGNING_SCHEME, default=SIGNING_SCHEME_RSA3072): cv.one_of( *SIGNING_SCHEMES, lower=True ), } @@ -1313,7 +1317,7 @@ def _validate_signed_ota_keys(config: ConfigType) -> ConfigType: path=[CONF_VERIFICATION_KEY], ) if has_verification_keys: - if scheme != "rsa3072": + if scheme != SIGNING_SCHEME_RSA3072: raise cv.Invalid( f"'{CONF_VERIFICATION_KEYS}' is only used with signing scheme " f"'rsa3072' (externally-signed RSA images). With '{scheme}' the " @@ -1340,7 +1344,7 @@ def _validate_signed_ota_keys(config: ConfigType) -> ConfigType: f"keys add nothing and waste a trusted-set slot).", path=[CONF_VERIFICATION_KEYS], ) - if scheme == "ecdsa_v1": + if scheme == SIGNING_SCHEME_ECDSA_V1: if not has_signing_key and not has_verification_key: raise cv.Invalid( f"Signing scheme 'ecdsa_v1' requires either '{CONF_SIGNING_KEY}' " @@ -1496,7 +1500,10 @@ def final_validate(config): ] # V1 ECDSA is only available on the original ESP32 - if scheme == "ecdsa_v1" and variant not in SIGNED_OTA_V1_ECDSA_VARIANTS: + if ( + scheme == SIGNING_SCHEME_ECDSA_V1 + and variant not in SIGNED_OTA_V1_ECDSA_VARIANTS + ): errs.append( cv.Invalid( f"Signing scheme 'ecdsa_v1' is only supported on " @@ -1509,7 +1516,9 @@ def final_validate(config): # On ESP32, V2 RSA requires minimum_chip_revision >= 3.0 # Note: string comparison works here because cv.one_of constrains # min_rev to known ESP32_CHIP_REVISIONS values ("0.0".."3.1"). - if scheme == "rsa3072" and (min_rev is None or min_rev < "3.0"): + if scheme == SIGNING_SCHEME_RSA3072 and ( + min_rev is None or min_rev < "3.0" + ): errs.append( cv.Invalid( f"Signing scheme 'rsa3072' on {VARIANT_FRIENDLY[variant]} " @@ -1520,7 +1529,7 @@ def final_validate(config): ) ) # ESP32 does not support V2 ECDSA (no SOC_SECURE_BOOT_V2_ECC) - elif scheme == "ecdsa256": + elif scheme == SIGNING_SCHEME_ECDSA256: errs.append( cv.Invalid( f"Signing scheme 'ecdsa256' is not supported on " @@ -1530,7 +1539,11 @@ def final_validate(config): ) ) # V1 on rev 3.0+ -- suggest V2 RSA for stronger security - elif scheme == "ecdsa_v1" and min_rev is not None and min_rev >= "3.0": + elif ( + scheme == SIGNING_SCHEME_ECDSA_V1 + and min_rev is not None + and min_rev >= "3.0" + ): _LOGGER.info( "Using Secure Boot V1 ECDSA on %s rev %s. " "Consider using 'rsa3072' (Secure Boot V2 RSA) for " @@ -1541,8 +1554,14 @@ def final_validate(config): else: # Non-ESP32 variants: check V2 scheme-variant compatibility scheme_variant_conflicts = { - "ecdsa256": (SIGNED_OTA_V2_RSA_ONLY_VARIANTS, "rsa3072"), - "rsa3072": (SIGNED_OTA_V2_ECC_ONLY_VARIANTS, "ecdsa256"), + SIGNING_SCHEME_ECDSA256: ( + SIGNED_OTA_V2_RSA_ONLY_VARIANTS, + SIGNING_SCHEME_RSA3072, + ), + SIGNING_SCHEME_RSA3072: ( + SIGNED_OTA_V2_ECC_ONLY_VARIANTS, + SIGNING_SCHEME_ECDSA256, + ), } if ( conflict := scheme_variant_conflicts.get(scheme) @@ -2703,7 +2722,9 @@ async def to_code(config): # n; the 4 KiB padding and reserved signature sector the verifier # depends on survive only because --secure-pad-v2 keys off # CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME (set below), not that symbol. - external_rsa = scheme == "rsa3072" and CONF_SIGNING_KEY not in signed_ota + external_rsa = ( + scheme == SIGNING_SCHEME_RSA3072 and CONF_SIGNING_KEY not in signed_ota + ) verification_keys = signed_ota.get(CONF_VERIFICATION_KEYS) # verification_keys is accepted only for external RSA (rsa3072 with no # signing_key), enforced in _validate_signed_ota_keys. Assert the