2626from cryptography .hazmat .primitives .asymmetric import ec , ed25519 , types , utils
2727from cryptography .x509 .oid import NameOID , ObjectIdentifier , SignatureAlgorithmOID
2828
29- from . import device
29+ from . import _root_keys , device
3030from .client import Session
3131from .tools import workflow
3232
@@ -41,6 +41,10 @@ def _pk_ed25519(pubkey_hex: str) -> PublicKey:
4141 return Ed25519PublicKey .from_bytes (bytes .fromhex (pubkey_hex ))
4242
4343
44+ def _pk_mldsa44 (pubkey_hex : str ) -> PublicKey :
45+ return Mldsa44PublicKey .from_bytes (bytes .fromhex (pubkey_hex ))
46+
47+
4448CHALLENGE_HEADER = b"AuthenticateDevice:"
4549
4650OID_TO_NAME = {
@@ -87,6 +91,9 @@ def from_bytes_and_oid(data: bytes, oid: ObjectIdentifier) -> PublicKey:
8791 return EcdsaPublicKey .from_bytes (data , ec .SECP256R1 ())
8892 elif oid == SignatureAlgorithmOID .ED25519 :
8993 return Ed25519PublicKey .from_bytes (data )
94+ # TODO replace after cryptography 47.0.0 is released
95+ elif oid == ObjectIdentifier ("2.16.840.1.101.3.4.3.17" ):
96+ return Mldsa44PublicKey .from_bytes (data )
9097 else :
9198 raise ValueError ("Unsupported key type." )
9299
@@ -96,6 +103,7 @@ def from_public_key(pubkey: types.CertificatePublicKeyTypes) -> PublicKey:
96103 return EcdsaPublicKey (pubkey )
97104 elif isinstance (pubkey , ed25519 .Ed25519PublicKey ):
98105 return Ed25519PublicKey (pubkey )
106+ # TODO after cryptography 47.0.0 is released
99107 else :
100108 raise ValueError ("Unsupported key type." )
101109
@@ -214,12 +222,35 @@ def verify_certificate(self, certificate: x509.Certificate) -> None:
214222 )
215223
216224
225+ class Mldsa44PublicKey (PublicKey ):
226+ def __init__ (self , pubkey : t .Any ) -> None :
227+ self .pubkey = pubkey
228+
229+ @classmethod
230+ def from_bytes (cls , data : bytes ) -> Mldsa44PublicKey :
231+ # TODO after cryptography 47.0.0 is released
232+ return cls (None )
233+
234+ def to_bytes (self ) -> bytes :
235+ # TODO after cryptography 47.0.0 is released
236+ return bytes ()
237+
238+ def verify_message (self , * , signature : bytes , message : bytes ) -> None :
239+ # TODO after cryptography 47.0.0 is released
240+ pass
241+
242+ def verify_certificate (self , certificate : x509 .Certificate ) -> None :
243+ # TODO after cryptography 47.0.0 is released
244+ pass
245+
246+
217247class RootCertificate (t .NamedTuple ):
218248 name : str
219249 device : str
220250 devel : bool
221251 p256_pubkey : PublicKey
222252 ed25519_pubkey : PublicKey | None = None
253+ mldsa44_pubkey : PublicKey | None = None
223254
224255 def pubkey_for_oid (self , oid : ObjectIdentifier ) -> PublicKey :
225256 if oid == SignatureAlgorithmOID .ECDSA_WITH_SHA256 :
@@ -228,6 +259,11 @@ def pubkey_for_oid(self, oid: ObjectIdentifier) -> PublicKey:
228259 if self .ed25519_pubkey is None :
229260 raise ValueError ("ED25519 public key not set." )
230261 return self .ed25519_pubkey
262+ # TODO replace after cryptography 47.0.0 is released
263+ elif oid == ObjectIdentifier ("2.16.840.1.101.3.4.3.17" ):
264+ if self .mldsa44_pubkey is None :
265+ raise ValueError ("ML-DSA-44 public key not set." )
266+ return self .mldsa44_pubkey
231267 else :
232268 raise ValueError ("Unsupported key type." )
233269
@@ -238,91 +274,69 @@ def pubkey_for_oid(self, oid: ObjectIdentifier) -> PublicKey:
238274 "Trezor Company" ,
239275 "Trezor Safe 3" ,
240276 False ,
241- _pk_p256 (
242- "04ca97480ac0d7b1e6efafe518cd433cec2bf8ab9822d76eafd34363b55d63e60"
243- "380bff20acc75cde03cffcb50ab6f8ce70c878e37ebc58ff7cca0a83b16b15fa5"
244- ),
277+ _pk_p256 (_root_keys .T2B1_DEV_AUTH_ROOT_PROD_P256_HEX ),
245278 ),
246279 RootCertificate (
247280 # Root production key for T3B1.
248281 "Trezor Company" ,
249282 "Trezor Safe 3" ,
250283 False ,
251- _pk_p256 (
252- "045b5c3fdd01f3602092834209b86df0ca86a9faf25cac35c73bf6237d66eb21e"
253- "afcec3706f1ccd5eb4cc7f2fa1751213eccb1c78389afba89a5788ff31ee46a5d"
254- ),
284+ _pk_p256 (_root_keys .T3B1_DEV_AUTH_ROOT_PROD_P256_HEX ),
255285 ),
256286 RootCertificate (
287+ # Root production key for T3T1.
257288 "Trezor Company" ,
258289 "Trezor Safe 5" ,
259290 False ,
260- _pk_p256 (
261- "041854b27fb1d9f65abb66828e78c9dc0ca301e66081ab0c6a4d104f9df1cd0ad"
262- "5a7c75f77a8c092f55cf825d2abaf734f934c9394d5e75f75a5a06a5ee9be93ae"
263- ),
291+ _pk_p256 (_root_keys .T3T1_DEV_AUTH_ROOT_PROD_P256_HEX ),
264292 ),
265293 RootCertificate (
266294 # Root production keys for T3W1.
267295 "Trezor Company" ,
268296 "Trezor Safe 7" ,
269297 False ,
270- _pk_p256 (
271- "040dde0d3e0d4da593fac6fd02a461d0e7eef238aca55c7c50b4e9ec37f387330"
272- "3b6429ef1c9b78b4411a7dcbbc5dde5225979c1c2da3b073e82b1ed3f5f9825bb"
273- ),
274- _pk_ed25519 ("59237acd17134061d655b3f8d624573ca06ce8d862f38ba4e05140ce1d3d609d" ),
298+ _pk_p256 (_root_keys .T3W1_DEV_AUTH_ROOT_PROD_P256_HEX ),
299+ _pk_ed25519 (_root_keys .T3W1_DEV_AUTH_ROOT_PROD_ED25519_HEX ),
300+ _pk_mldsa44 (_root_keys .T3W1_DEV_AUTH_ROOT_PROD_MLDSA44_HEX ),
275301 ),
276302 RootCertificate (
277303 # Root backup production keys for T3W1.
278304 "Trezor Company" ,
279305 "Trezor Safe 7" ,
280306 False ,
281- _pk_p256 (
282- "04c6a673af4ec44b10441b1d78676e15173ad0e36df9f7f2fa1cd819955f20fe3"
283- "2917b60da5fed3b3aa54a9ab8b3ed27d198b3768cad26eef5935cd87af0af065e"
284- ),
285- _pk_ed25519 ("5612606584ee7e0bc313b13f7ac94156bb4cb75bd77585ddbe579301306e85f1" ),
307+ _pk_p256 (_root_keys .T3W1_DEV_AUTH_ROOT_PROD_BACKUP_P256_HEX ),
308+ _pk_ed25519 (_root_keys .T3W1_DEV_AUTH_ROOT_PROD_BACKUP_ED25519_HEX ),
309+ _pk_mldsa44 (_root_keys .T3W1_DEV_AUTH_ROOT_PROD_BACKUP_MLDSA44_HEX ),
286310 ),
287311 RootCertificate (
288312 # Root debug key for T2B1 and T3B1.
289313 "TESTING ENVIRONMENT. DO NOT USE THIS DEVICE" ,
290314 "Trezor Safe 3" ,
291315 True ,
292- _pk_p256 (
293- "047f77368dea2d4d61e989f474a56723c3212dacf8a808d8795595ef38441427c"
294- "4389bc454f02089d7f08b873005e4c28d432468997871c0bf286fd3861e21e96a"
295- ),
316+ _pk_p256 (_root_keys .T2B1_DEV_AUTH_ROOT_DEBUG_P256_HEX ),
296317 ),
297318 RootCertificate (
319+ # Root debug key for T3T1.
298320 "TESTING ENVIRONMENT. DO NOT USE THIS DEVICE" ,
299321 "Trezor Safe 5" ,
300322 True ,
301- _pk_p256 (
302- "04e48b69cd7962068d3cca3bcc6b1747ef496c1e28b5529e34ad7295215ea161d"
303- "be8fb08ae0479568f9d2cb07630cb3e52f4af0692102da5873559e45e9fa72959"
304- ),
323+ _pk_p256 (_root_keys .T3T1_DEV_AUTH_ROOT_DEBUG_P256_HEX ),
305324 ),
306325 RootCertificate (
307326 # Root debug keys for T3W1.
308327 "TESTING ENVIRONMENT. DO NOT USE THIS DEVICE" ,
309328 "Trezor Safe 7" ,
310329 True ,
311- _pk_p256 (
312- "04521192e173a9da4e3023f747d836563725372681eba3079c56ff11b2fc137ab"
313- "189eb4155f371127651b5594f8c332fc1e9c0f3b80d4212822668b63189706578"
314- ),
330+ _pk_p256 (_root_keys .T3W1_DEV_AUTH_ROOT_DEBUG_P256_HEX ),
315331 ),
316332 RootCertificate (
317333 # Root staging keys for T3W1.
318334 "TESTING ENVIRONMENT. DO NOT USE THIS DEVICE" ,
319335 "Trezor Safe 7" ,
320- False ,
321- _pk_p256 (
322- "0465e88f9b2cea67e8364f0cfcfacd500af24e9040b357beee629ccc4fce1704d"
323- "1a7ef7284f387708f92ef14600e2caad6894016fee819d623b95d66210c3e7519"
324- ),
325- _pk_ed25519 ("cd318dc8405ae4f4144e3284dcb7b0cb0f0c2195c2ca14a0f6fccd9104e32a4b" ),
336+ True ,
337+ _pk_p256 (_root_keys .T3W1_DEV_AUTH_ROOT_STAGING_P256_HEX ),
338+ _pk_ed25519 (_root_keys .T3W1_DEV_AUTH_ROOT_STAGING_ED25519_HEX ),
339+ _pk_mldsa44 (_root_keys .T3W1_DEV_AUTH_ROOT_STAGING_MLDSA44_HEX ),
326340 ),
327341]
328342
@@ -550,6 +564,7 @@ def authenticate_device(
550564 allow_development_devices : bool = False ,
551565 p256_root_pubkey : bytes | PublicKey | None = None ,
552566 ed25519_root_pubkey : bytes | PublicKey | None = None ,
567+ mldsa44_root_pubkey : bytes | PublicKey | None = None ,
553568) -> None :
554569 if challenge is None :
555570 challenge = secrets .token_bytes (16 )
@@ -585,3 +600,24 @@ def authenticate_device(
585600 if optiga_root is not tropic_root :
586601 LOG .error ("Certificates issued by different root authorities." )
587602 raise DeviceNotAuthentic
603+
604+ if (
605+ getattr (optiga_root , "mldsa44_pubkey" , None ) is not None
606+ or mldsa44_root_pubkey is not None
607+ ):
608+ if not resp .mcu_signature :
609+ LOG .error ("Missing MCU signature." )
610+ raise DeviceNotAuthentic
611+
612+ mcu_root = verify_authentication_response (
613+ challenge ,
614+ resp .mcu_signature ,
615+ resp .mcu_certificates ,
616+ allowlist = allowlist ,
617+ allow_development_devices = allow_development_devices ,
618+ root_pubkey = mldsa44_root_pubkey ,
619+ )
620+
621+ if optiga_root is not mcu_root :
622+ LOG .error ("Certificates issued by different root authorities." )
623+ raise DeviceNotAuthentic
0 commit comments