Skip to content

Commit ea7dd06

Browse files
committed
suit: Add support for Ed25519PH
Ref: NCSDK-31353 Signed-off-by: Artur Hadasz <[email protected]>
1 parent 7f4ca54 commit ea7dd06

File tree

6 files changed

+34
-3
lines changed

6 files changed

+34
-3
lines changed

ncs/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ config SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_384
176176
config SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_521
177177
bool "Use the ECDSA algorithm with key length of 521 bits"
178178

179+
config SUIT_ENVELOPE_TARGET_SIGN_ALG_HASHED_EDDSA
180+
bool "Use the Hashed EdDSA algorithm (specifically: ed25519ph)"
181+
179182
endchoice
180183

181184
config SUIT_ENVELOPE_TARGET_SIGN_ALG_NAME
@@ -184,5 +187,6 @@ config SUIT_ENVELOPE_TARGET_SIGN_ALG_NAME
184187
default "es-256" if SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_256
185188
default "es-384" if SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_384
186189
default "es-521" if SUIT_ENVELOPE_TARGET_SIGN_ALG_ECDSA_521
190+
default "hashed-eddsa" if SUIT_ENVELOPE_TARGET_SIGN_ALG_HASHED_EDDSA
187191

188192
endif # SUIT_ENVELOPE_TARGET_SIGN

ncs/basic_kms.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
from cryptography.hazmat.primitives.asymmetric import ec
1818
from cryptography.hazmat.primitives import hashes
1919
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
20+
# eddsa25519ph is not supported by cryptography, so we need to use pycryptodome
21+
from Crypto.PublicKey import ECC
22+
from Crypto.Signature import eddsa
23+
from Crypto.Hash import SHA512
2024
import math
2125

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

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

107-
def _get_sign_method(self, private_key) -> bool:
111+
def _create_cose_ed_prehashed_signature(self, input_data, private_key) -> bytes:
112+
prehashed_message = SHA512.new(input_data)
113+
key = ECC.import_key(private_key)
114+
signer = eddsa.new(key, 'rfc8032')
115+
return signer.sign(prehashed_message)
116+
117+
def _get_sign_method(self, private_key, algorithm) -> bool:
108118
"""Return sign method based on key type."""
109119
if isinstance(private_key, EllipticCurvePrivateKey):
110120
return self._create_cose_es_signature
111121
elif isinstance(private_key, Ed25519PrivateKey) or isinstance(private_key, Ed448PrivateKey):
122+
if algorithm == "hashed-eddsa":
123+
return self._create_cose_ed_prehashed_signature
112124
return self._create_cose_ed_signature
113125
else:
114126
raise ValueError(f"Key {type(private_key)} not supported")
@@ -146,7 +158,13 @@ def sign(self, data: bytes, key_name: str, algorithm: str, context: str) -> byte
146158
if not self._verify_signing_key_type(private_key, algorithm):
147159
raise ValueError(f"Key {key_file_name} is not compatible with algorithm {algorithm}")
148160

149-
sign_method = self._get_sign_method(private_key)
161+
sign_method = self._get_sign_method(private_key, algorithm)
162+
163+
if algorithm == "hashed-eddsa":
164+
# In the special case of hashed-eddsa, we need to use pycryptodome, which needs the raw key
165+
# data to import the key
166+
private_key = open(private_key_path).read()
167+
150168
signature = sign_method(data, private_key)
151169

152170
return signature

ncs/sign_script.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class SuitCoseSignAlgorithms(Enum):
3636
COSE_ALG_ES_384 = -35
3737
COSE_ALG_ES_521 = -36
3838
COSE_ALG_EdDSA = -8
39+
COSE_ALG_VS_HashedEdDSA = -65537
3940

4041

4142
class SuitIds(Enum):

suit_generator/suit/security.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
cose_alg_es_384,
4848
cose_alg_es_521,
4949
cose_alg_eddsa,
50+
cose_alg_vs_hashed_eddsa,
5051
cose_alg_aes_gcm_128,
5152
cose_alg_aes_gcm_192,
5253
cose_alg_aes_gcm_256,
@@ -183,6 +184,7 @@ class SuitcoseAlg(SuitEnum):
183184
cose_alg_es_384,
184185
cose_alg_es_521,
185186
cose_alg_eddsa,
187+
cose_alg_vs_hashed_eddsa,
186188
cose_alg_aes_gcm_128,
187189
cose_alg_aes_gcm_192,
188190
cose_alg_aes_gcm_256,

suit_generator/suit/types/keys.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,11 @@ class cose_alg_eddsa(suit_key):
693693
id = -8
694694
name = "cose-alg-eddsa"
695695

696+
class cose_alg_vs_hashed_eddsa(suit_key):
697+
"""Cose algorithm metadata."""
698+
699+
id = -65537
700+
name = "cose-alg-vs-hashed-eddsa"
696701

697702
class cose_alg_aes_gcm_128(suit_key):
698703
"""Cose algorithm metadata."""

suit_generator/suit_sign_script_base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class SuitSignAlgorithms(Enum):
1919
ES_384 = "es-384"
2020
ES_521 = "es-521"
2121
EdDSA = "eddsa"
22+
VS_HashedEdDSA = "hashed-eddsa"
2223

2324
def __str__(self):
2425
return self.value

0 commit comments

Comments
 (0)