Skip to content

Commit

Permalink
suit: Add support for Ed25519PH
Browse files Browse the repository at this point in the history
Ref: NCSDK-31353

Signed-off-by: Artur Hadasz <[email protected]>
  • Loading branch information
ahasztag committed Jan 23, 2025
1 parent 7f4ca54 commit 58b9c3e
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 3 deletions.
5 changes: 5 additions & 0 deletions ncs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ config SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_384
config SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_521
bool "Use the ECDSA algorithm with key length of 521 bits"

config SUIT_ENVELOPE_TARGET_SIGN_ALG_HASHED_EDDSA
bool "Use the Hashed EdDSA algorithm (specifically: ed25519ph)"
select EXPERIMENTAL

endchoice

config SUIT_ENVELOPE_TARGET_SIGN_ALG_NAME
Expand All @@ -184,5 +188,6 @@ config SUIT_ENVELOPE_TARGET_SIGN_ALG_NAME
default "es-256" if SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_256
default "es-384" if SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_384
default "es-521" if SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_521
default "hashed-eddsa" if SUIT_ENVELOPE_TARGET_SIGN_ALG_HASHED_EDDSA

endif # SUIT_ENVELOPE_TARGET_SIGN
24 changes: 21 additions & 3 deletions ncs/basic_kms.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
# eddsa25519ph is not supported by cryptography, so we need to use pycryptodome
from Crypto.PublicKey import ECC
from Crypto.Signature import eddsa
from Crypto.Hash import SHA512
import math

from suit_generator.suit_kms_base import SuitKMSBase
Expand Down Expand Up @@ -87,7 +91,7 @@ def _verify_signing_key_type(self, private_key, algorithm: str) -> bool:
if isinstance(private_key, EllipticCurvePrivateKey):
return f"es-{private_key.key_size}" == algorithm
elif isinstance(private_key, Ed25519PrivateKey) or isinstance(private_key, Ed448PrivateKey):
return "eddsa" == algorithm
return "eddsa" == algorithm or "hashed-eddsa" == algorithm
else:
raise ValueError(f"Key {type(private_key)} not supported")

Expand All @@ -104,11 +108,19 @@ def _create_cose_ed_signature(self, input_data, private_key) -> bytes:
"""Create ECDSA signature and return signature bytes."""
return private_key.sign(input_data)

def _get_sign_method(self, private_key) -> bool:
def _create_cose_ed_prehashed_signature(self, input_data, private_key) -> bytes:
prehashed_message = SHA512.new(input_data)
key = ECC.import_key(private_key)
signer = eddsa.new(key, 'rfc8032')
return signer.sign(prehashed_message)

def _get_sign_method(self, private_key, algorithm) -> bool:
"""Return sign method based on key type."""
if isinstance(private_key, EllipticCurvePrivateKey):
return self._create_cose_es_signature
elif isinstance(private_key, Ed25519PrivateKey) or isinstance(private_key, Ed448PrivateKey):
if algorithm == "hashed-eddsa":
return self._create_cose_ed_prehashed_signature
return self._create_cose_ed_signature
else:
raise ValueError(f"Key {type(private_key)} not supported")
Expand Down Expand Up @@ -146,7 +158,13 @@ def sign(self, data: bytes, key_name: str, algorithm: str, context: str) -> byte
if not self._verify_signing_key_type(private_key, algorithm):
raise ValueError(f"Key {key_file_name} is not compatible with algorithm {algorithm}")

sign_method = self._get_sign_method(private_key)
sign_method = self._get_sign_method(private_key, algorithm)

if algorithm == "hashed-eddsa":
# In the special case of hashed-eddsa, we need to use pycryptodome, which needs the raw key
# data to import the key
private_key = open(private_key_path).read()

signature = sign_method(data, private_key)

return signature
Expand Down
1 change: 1 addition & 0 deletions ncs/sign_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class SuitCoseSignAlgorithms(Enum):
COSE_ALG_ES_384 = -35
COSE_ALG_ES_521 = -36
COSE_ALG_EdDSA = -8
COSE_ALG_VS_HashedEdDSA = -65537


class SuitIds(Enum):
Expand Down
2 changes: 2 additions & 0 deletions suit_generator/suit/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
cose_alg_es_384,
cose_alg_es_521,
cose_alg_eddsa,
cose_alg_vs_hashed_eddsa,
cose_alg_aes_gcm_128,
cose_alg_aes_gcm_192,
cose_alg_aes_gcm_256,
Expand Down Expand Up @@ -183,6 +184,7 @@ class SuitcoseAlg(SuitEnum):
cose_alg_es_384,
cose_alg_es_521,
cose_alg_eddsa,
cose_alg_vs_hashed_eddsa,
cose_alg_aes_gcm_128,
cose_alg_aes_gcm_192,
cose_alg_aes_gcm_256,
Expand Down
5 changes: 5 additions & 0 deletions suit_generator/suit/types/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,11 @@ class cose_alg_eddsa(suit_key):
id = -8
name = "cose-alg-eddsa"

class cose_alg_vs_hashed_eddsa(suit_key):
"""Cose algorithm metadata."""

id = -65537
name = "cose-alg-vs-hashed-eddsa"

class cose_alg_aes_gcm_128(suit_key):
"""Cose algorithm metadata."""
Expand Down
1 change: 1 addition & 0 deletions suit_generator/suit_sign_script_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class SuitSignAlgorithms(Enum):
ES_384 = "es-384"
ES_521 = "es-521"
EdDSA = "eddsa"
VS_HashedEdDSA = "hashed-eddsa"

def __str__(self):
return self.value
Expand Down

0 comments on commit 58b9c3e

Please sign in to comment.