iat-verifier: update Secure lifecycle claim
Update Secure lifecycle claim based on
https://www.ietf.org/archive/id/draft-tschofenig-rats-psa-token-21.html
Change-Id: Id455ec764ceed0ea21eee6c30aec7ccf4b1ad3c7
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/iat-verifier/dev_scripts/generate-sample-iat.py b/iat-verifier/dev_scripts/generate-sample-iat.py
index 84985de..cf0f700 100755
--- a/iat-verifier/dev_scripts/generate-sample-iat.py
+++ b/iat-verifier/dev_scripts/generate-sample-iat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -----------------------------------------------------------------------------
-# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -45,7 +45,7 @@
ImplementationIdClaim.get_claim_key(): ORIGIN,
ChallengeClaim.get_claim_key(): NONCE,
ClientIdClaim.get_claim_key(): 2,
- SecurityLifecycleClaim.get_claim_key(): SecurityLifecycleClaim.SL_SECURED,
+ SecurityLifecycleClaim.get_claim_key(): 0x1000,
ProfileIdClaim.get_claim_key(): 'http://example.com',
BootSeedClaim.get_claim_key(): BOOT_SEED,
SWComponentsClaim.get_claim_key(): [
diff --git a/iat-verifier/iatverifier/cca_claims.py b/iat-verifier/iatverifier/cca_claims.py
index d176656..7948425 100644
--- a/iat-verifier/iatverifier/cca_claims.py
+++ b/iat-verifier/iatverifier/cca_claims.py
@@ -1,5 +1,5 @@
# -----------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -9,6 +9,7 @@
import logging
from iatverifier.attest_token_verifier import AttestationClaim, CompositeAttestClaim
+from iatverifier.lifecycle_claim import GenericLifecycleClaim
logger = logging.getLogger('iat-verifiers')
@@ -167,7 +168,7 @@
def verify(self, token_item):
self._check_type(self.get_claim_name(), token_item.value, bytes)
-class CCAPlatformLifecycleClaim(AttestationClaim):
+class CCAPlatformLifecycleClaim(GenericLifecycleClaim):
SL_VALUES= [
("UNKNOWN", 0x0000, 0x00ff),
@@ -185,45 +186,6 @@
def get_claim_name(self=None):
return 'CCA_PLATFORM_LIFECYCLE'
- @classmethod
- def parse_raw(cls, raw_value):
- try:
- int_value = int(raw_value, 16)
- except ValueError:
- # It is not a hex number. Try to decode known text values
- pass
- for text, min, max in cls.SL_VALUES:
- if raw_value.startswith(text.lower()):
- raw_value = raw_value[len(text):]
- else:
- continue
- if len(raw_value) == 0:
- return min
- assert raw_value.startswith("_0x")
- raw_value = raw_value[3:]
- int_value = int(raw_value, 16)
- assert(min <= int_value <= max)
- return int_value
- assert False
-
- @classmethod
- def get_formatted_value(cls, value):
- for text, min, max in cls.SL_VALUES:
- if min <= value <= max:
- return f"{text}_{value:04x}".lower()
- return f"INVALID_{value:04x}"
-
- def verify(self, token_item):
- self._check_type(self.get_claim_name, token_item.value, int)
- value_valid = False
- for _, min, max in CCAPlatformLifecycleClaim.SL_VALUES:
- if min <= token_item.value <= max:
- value_valid = True
- break
- if not value_valid:
- msg = 'Invalid Platform Lifecycle claim "0x{:02x}"'
- self.verifier.error(msg.format(token_item.value))
-
class CCASwCompHashAlgIdClaim(AttestationClaim):
def get_claim_key(self=None):
return 6
diff --git a/iat-verifier/iatverifier/lifecycle_claim.py b/iat-verifier/iatverifier/lifecycle_claim.py
new file mode 100644
index 0000000..4503d31
--- /dev/null
+++ b/iat-verifier/iatverifier/lifecycle_claim.py
@@ -0,0 +1,50 @@
+# -----------------------------------------------------------------------------
+# Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# -----------------------------------------------------------------------------
+
+from abc import ABC, abstractmethod
+from iatverifier.attest_token_verifier import AttestationClaim
+
+class GenericLifecycleClaim(AttestationClaim):
+
+ @classmethod
+ def parse_raw(cls, raw_value):
+ try:
+ int_value = int(raw_value, 16)
+ except ValueError:
+ # It is not a hex number. Try to decode known text values
+ pass
+ for text, min, max in cls.SL_VALUES:
+ if raw_value.startswith(text.lower()):
+ raw_value = raw_value[len(text):]
+ else:
+ continue
+ if len(raw_value) == 0:
+ return min
+ assert raw_value.startswith("_0x")
+ raw_value = raw_value[3:]
+ int_value = int(raw_value, 16)
+ assert(min <= int_value <= max)
+ return int_value
+ assert False
+
+ @classmethod
+ def get_formatted_value(cls, value):
+ for text, min, max in cls.SL_VALUES:
+ if min <= value <= max:
+ return f"{text}_{value:04x}".lower()
+ return f"INVALID_{value:04x}"
+
+ def verify(self, token_item):
+ self._check_type(self.get_claim_name, token_item.value, int)
+ value_valid = False
+ for _, min, max in self.SL_VALUES:
+ if min <= token_item.value <= max:
+ value_valid = True
+ break
+ if not value_valid:
+ msg = 'Invalid Lifecycle claim "0x{:02x}"'
+ self.verifier.error(msg.format(token_item.value))
diff --git a/iat-verifier/iatverifier/psa_2_0_0_token_claims.py b/iat-verifier/iatverifier/psa_2_0_0_token_claims.py
index 06f0e78..f5287c8 100644
--- a/iat-verifier/iatverifier/psa_2_0_0_token_claims.py
+++ b/iat-verifier/iatverifier/psa_2_0_0_token_claims.py
@@ -1,5 +1,5 @@
# -----------------------------------------------------------------------------
-# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -9,6 +9,7 @@
from iatverifier.attest_token_verifier import AttestationClaim
from iatverifier.attest_token_verifier import CompositeAttestClaim
+from iatverifier.lifecycle_claim import GenericLifecycleClaim
# IAT custom claims
ARM_RANGE = 2393
@@ -121,46 +122,24 @@
def verify(self, token_item):
self._check_type('CLIENT_ID', token_item.value, int)
-class SecurityLifecycleClaim(AttestationClaim):
+class SecurityLifecycleClaim(GenericLifecycleClaim):
"""Class representing a PSA Attestation Token Security Lifecycle claim"""
- SL_SHIFT = 12
-
- SL_NAMES = [
- 'SL_UNKNOWN',
- 'SL_PSA_ROT_PROVISIONING',
- 'SL_SECURED',
- 'SL_NON_PSA_ROT_DEBUG',
- 'SL_RECOVERABLE_PSA_ROT_DEBUG',
- 'SL_PSA_LIFECYCLE_DECOMMISSIONED',
+ SL_VALUES= [
+ ("SL_UNKNOWN", 0x0000, 0x00ff),
+ ("SL_ASSEMBLY_AND_TEST", 0x1000, 0x10ff),
+ ("SL_PSA_ROT_PROVISIONING", 0x2000, 0x20ff),
+ ("SL_SECURED", 0x3000, 0x30ff),
+ ("SL_NON_PSA_ROT_DEBUG", 0x4000, 0x40ff),
+ ("SL_RECOVERABLE_PSA_ROT_DEBUG", 0x5000, 0x50ff),
+ ("SL_DECOMMISSIONED", 0x6000, 0x60ff),
]
- # Security Lifecycle claims
- SL_UNKNOWN = 0x1000
- SL_PSA_ROT_PROVISIONING = 0x2000
- SL_SECURED = 0x3000
- SL_NON_PSA_ROT_DEBUG = 0x4000
- SL_RECOVERABLE_PSA_ROT_DEBUG = 0x5000
- SL_PSA_LIFECYCLE_DECOMMISSIONED = 0x6000
-
def get_claim_key(self=None):
return ARM_RANGE + 2
def get_claim_name(self=None):
return 'SECURITY_LIFECYCLE'
- def verify(self, token_item):
- self._check_type('SECURITY_LIFECYCLE', token_item.value, int)
-
- @staticmethod
- def parse_raw(raw_value):
- name_idx = SecurityLifecycleClaim.SL_NAMES.index(raw_value.upper())
- return (name_idx + 1) << SecurityLifecycleClaim.SL_SHIFT
-
- @staticmethod
- def get_formatted_value(value):
- return SecurityLifecycleClaim.SL_NAMES[(value >> SecurityLifecycleClaim.SL_SHIFT) - 1]
-
-
class ProfileIdClaim(AttestationClaim):
"""Class representing a PSA Attestation Token Profile Definition claim"""
def get_claim_key(self=None):
diff --git a/iat-verifier/iatverifier/psa_iot_profile1_token_claims.py b/iat-verifier/iatverifier/psa_iot_profile1_token_claims.py
index a51b544..8fc2b4d 100644
--- a/iat-verifier/iatverifier/psa_iot_profile1_token_claims.py
+++ b/iat-verifier/iatverifier/psa_iot_profile1_token_claims.py
@@ -1,5 +1,5 @@
# -----------------------------------------------------------------------------
-# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -13,6 +13,7 @@
from iatverifier.attest_token_verifier import AttestationClaim
from iatverifier.attest_token_verifier import CompositeAttestClaim
+from iatverifier.lifecycle_claim import GenericLifecycleClaim
# IAT custom claims
ARM_RANGE = -75000
@@ -136,46 +137,24 @@
def verify(self, token_item):
self._check_type('CLIENT_ID', token_item.value, int)
-class SecurityLifecycleClaim(AttestationClaim):
+class SecurityLifecycleClaim(GenericLifecycleClaim):
"""Class representing a PSA Attestation Token Security Lifecycle claim"""
- SL_SHIFT = 12
-
- SL_NAMES = [
- 'SL_UNKNOWN',
- 'SL_PSA_ROT_PROVISIONING',
- 'SL_SECURED',
- 'SL_NON_PSA_ROT_DEBUG',
- 'SL_RECOVERABLE_PSA_ROT_DEBUG',
- 'SL_PSA_LIFECYCLE_DECOMMISSIONED',
+ SL_VALUES= [
+ ("SL_UNKNOWN", 0x0000, 0x00ff),
+ ("SL_ASSEMBLY_AND_TEST", 0x1000, 0x10ff),
+ ("SL_PSA_ROT_PROVISIONING", 0x2000, 0x20ff),
+ ("SL_SECURED", 0x3000, 0x30ff),
+ ("SL_NON_PSA_ROT_DEBUG", 0x4000, 0x40ff),
+ ("SL_RECOVERABLE_PSA_ROT_DEBUG", 0x5000, 0x50ff),
+ ("SL_DECOMMISSIONED", 0x6000, 0x60ff),
]
- # Security Lifecycle claims
- SL_UNKNOWN = 0x1000
- SL_PSA_ROT_PROVISIONING = 0x2000
- SL_SECURED = 0x3000
- SL_NON_PSA_ROT_DEBUG = 0x4000
- SL_RECOVERABLE_PSA_ROT_DEBUG = 0x5000
- SL_PSA_LIFECYCLE_DECOMMISSIONED = 0x6000
-
def get_claim_key(self=None):
return ARM_RANGE - 2
def get_claim_name(self=None):
return 'SECURITY_LIFECYCLE'
- def verify(self, token_item):
- self._check_type('SECURITY_LIFECYCLE', token_item.value, int)
-
- @classmethod
- def parse_raw(cls, raw_value):
- name_idx = cls.SL_NAMES.index(raw_value.upper())
- return (name_idx + 1) << cls.SL_SHIFT
-
- @classmethod
- def get_formatted_value(cls, value):
- return cls.SL_NAMES[(value >> cls.SL_SHIFT) - 1]
-
-
class ProfileIdClaim(AttestationClaim):
"""Class representing a PSA Attestation Token Profile Definition claim"""
def get_claim_key(self=None):
diff --git a/iat-verifier/tests/test_verifier.py b/iat-verifier/tests/test_verifier.py
index 8f64be8..2b7fe92 100644
--- a/iat-verifier/tests/test_verifier.py
+++ b/iat-verifier/tests/test_verifier.py
@@ -1,5 +1,5 @@
# -----------------------------------------------------------------------------
-# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -252,7 +252,7 @@
cose_alg=cose_alg,
signing_key=signing_key,
configuration=self.config)).get_token_map()
- self.assertEqual(iat['SECURITY_LIFECYCLE'], 'SL_SECURED')
+ self.assertEqual(iat['SECURITY_LIFECYCLE'], 'sl_secured_3000')
def test_security_lifecycle_decoding(self):
"""Test security lifecycle decoding"""
@@ -266,4 +266,4 @@
cose_alg=cose_alg,
signing_key=signing_key,
configuration=self.config)).get_token_map()
- self.assertEqual(iat['SECURITY_LIFECYCLE'], 'SL_SECURED')
+ self.assertEqual(iat['SECURITY_LIFECYCLE'], 'sl_secured_3000')