Add attestation claim sources for device claims

Adds claim sources that add device specific information to a
generated attestation report.  Different claim sources may
be used for different deployments to accommodate platform
differences.

This commit contains derived work, the following files are copied
    from other projects:

    components/service/attestation/include/psa/lifecycle.h
       Origin:
            https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git
            interface/include/psa/lifecycle.h
            #9280ae9d898bffbb889e4796e51aab35a392ef82

Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I5a6e3782ff936a5b2db46c79e159524ae89b61c4
diff --git a/components/service/attestation/claims/claims_register.h b/components/service/attestation/claims/claims_register.h
index 9953633..b4029f0 100644
--- a/components/service/attestation/claims/claims_register.h
+++ b/components/service/attestation/claims/claims_register.h
@@ -55,8 +55,8 @@
  * Used by a report generator to obtain claims that correspond to
  * a particular category.
  *
-  * \param[in] category  Claim category
- * \param[out] result   Qualifying claims are added the result claim_vector
+ * \param[in] category  Claim category
+ * \param[out] result   Qualifying claims are added to the result claim_vector
  */
 void claims_register_query_by_category(enum claim_category category,
                                 struct claim_vector *result);
diff --git a/components/service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.c b/components/service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.c
new file mode 100644
index 0000000..53d4e7c
--- /dev/null
+++ b/components/service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa/crypto.h>
+#include <service/attestation/claims/claim.h>
+#include "boot_seed_generator.h"
+
+static bool boot_seed_generator_get_claim(void *context, struct claim *claim);
+
+
+struct claim_source *boot_seed_generator_init(struct boot_seed_generator *instance)
+{
+    instance->base.get_claim = boot_seed_generator_get_claim;
+    instance->base.context = instance;
+
+    instance->is_generated = false;
+
+    return &instance->base;
+}
+
+static bool boot_seed_generator_get_claim(void *context, struct claim *claim)
+{
+    struct boot_seed_generator *instance = (struct boot_seed_generator*)context;
+
+    /* Generate if no seed has been generated yet */
+    if (!instance->is_generated) {
+
+        psa_status_t status;
+        status = psa_generate_random(instance->boot_seed, sizeof(instance->boot_seed));
+        instance->is_generated = (status == PSA_SUCCESS);
+    }
+
+    if (instance->is_generated) {
+
+        claim->category = CLAIM_CATEGORY_DEVICE;
+        claim->subject_id = CLAIM_SUBJECT_ID_BOOT_SEED;
+        claim->variant_id = CLAIM_VARIANT_ID_BYTE_STRING;
+        claim->raw_data = NULL;
+
+        claim->variant.byte_string.bytes = instance->boot_seed;
+        claim->variant.byte_string.len = sizeof(instance->boot_seed);
+    }
+
+    return instance->is_generated;
+}
diff --git a/components/service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.h b/components/service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.h
new file mode 100644
index 0000000..4b470aa
--- /dev/null
+++ b/components/service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BOOT_SEED_GENERATOR_H
+#define BOOT_SEED_GENERATOR_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <service/attestation/claims/claim_source.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A claim source for generating and accessing a boot seed.
+ * The boot seed is a random number that forms an identifier for
+ * a particular boot session.  On each re-boot, a new boot seed is
+ * generated.  By including the boot seed in an attestation report,
+ * reports associated with the same boot session may be identified.
+ * Use this claim source in a deployment when no boot seed is passed
+ * forward by the boot loader or when no other authoritative source of
+ * boot seed is available.
+ */
+struct boot_seed_generator
+{
+    struct claim_source base;
+
+    bool is_generated;
+    uint8_t boot_seed[32];
+};
+
+/**
+ * \brief Initializes a struct boot_seed_generator
+ *
+ * \param[in] instance      The instance to initialze
+ *
+ * \return The initialize base claim_source structure
+ */
+struct claim_source *boot_seed_generator_init(struct boot_seed_generator *instance);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* BOOT_SEED_GENERATOR_H */
diff --git a/components/service/attestation/claims/sources/boot_seed_generator/component.cmake b/components/service/attestation/claims/sources/boot_seed_generator/component.cmake
new file mode 100644
index 0000000..7e30def
--- /dev/null
+++ b/components/service/attestation/claims/sources/boot_seed_generator/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/boot_seed_generator.c"
+	)
diff --git a/components/service/attestation/claims/sources/event_log/event_log_claim_source.h b/components/service/attestation/claims/sources/event_log/event_log_claim_source.h
index 8e85166..4a79e27 100644
--- a/components/service/attestation/claims/sources/event_log/event_log_claim_source.h
+++ b/components/service/attestation/claims/sources/event_log/event_log_claim_source.h
@@ -17,8 +17,10 @@
 #endif
 
 /**
- * A claim source for accessing a TCG event log, stored as
- * a contiguous array of bytes.
+ * A claim source for accessing a TCG event log, stored in a buffer.
+ * Use this claim source in deployments where the bootloader has peformed
+ * boot measurements and recorded them in an event log.  Additional
+ * claims such as the boot seed may also be recorded in the event log.
  */
 struct event_log_claim_source
 {
diff --git a/components/service/attestation/claims/sources/instance_id/component.cmake b/components/service/attestation/claims/sources/instance_id/component.cmake
new file mode 100644
index 0000000..58e16ee
--- /dev/null
+++ b/components/service/attestation/claims/sources/instance_id/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/instance_id_claim_source.c"
+	)
diff --git a/components/service/attestation/claims/sources/instance_id/instance_id_claim_source.c b/components/service/attestation/claims/sources/instance_id/instance_id_claim_source.c
new file mode 100644
index 0000000..a1222ee
--- /dev/null
+++ b/components/service/attestation/claims/sources/instance_id/instance_id_claim_source.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <psa/crypto.h>
+#include <service/attestation/claims/claim.h>
+#include <service/attestation/key_mngr/attest_key_mngr.h>
+#include "instance_id_claim_source.h"
+
+static bool instance_id_claim_source_get_claim(void *context, struct claim *claim);
+static bool prepare_instance_id(struct instance_id_claim_source *instance);
+static bool cal_iak_hash(struct instance_id_claim_source *instance,
+    const uint8_t *key_buf, size_t key_len);
+
+struct claim_source *instance_id_claim_source_init(struct instance_id_claim_source *instance)
+{
+    instance->base.get_claim = instance_id_claim_source_get_claim;
+    instance->base.context = instance;
+
+    instance->is_known = false;
+
+    return &instance->base;
+}
+
+static bool instance_id_claim_source_get_claim(void *context, struct claim *claim)
+{
+    struct instance_id_claim_source *instance = (struct instance_id_claim_source*)context;
+
+    if (!instance->is_known)
+        instance->is_known = prepare_instance_id(instance);
+
+    if (instance->is_known) {
+
+        claim->category = CLAIM_CATEGORY_DEVICE;
+        claim->subject_id = CLAIM_SUBJECT_ID_INSTANCE_ID;
+        claim->variant_id = CLAIM_VARIANT_ID_BYTE_STRING;
+        claim->raw_data = NULL;
+
+        claim->variant.byte_string.bytes = instance->instance_id;
+        claim->variant.byte_string.len = sizeof(instance->instance_id);
+    }
+
+    return instance->is_known;
+}
+
+static bool prepare_instance_id(struct instance_id_claim_source *instance)
+{
+    bool success = false;
+    size_t key_buf_size =  attest_key_mngr_max_iak_export_size();
+    uint8_t *key_buf = malloc(key_buf_size);
+
+    if (key_buf) {
+
+        size_t key_len;
+        int status;
+
+        status = attest_key_mngr_export_iak_public_key(key_buf, key_buf_size, &key_len);
+
+        if (status == PSA_SUCCESS) {
+
+            success = cal_iak_hash(instance, key_buf, key_len);
+
+            /* Add the UEID type */
+            instance->instance_id[0] = 0x01;
+        }
+
+        free(key_buf);
+    }
+
+    return success;
+}
+
+static bool cal_iak_hash(struct instance_id_claim_source *instance,
+    const uint8_t *key_buf, size_t key_len)
+{
+    int status;
+    size_t hash_len;
+
+    psa_hash_operation_t op = psa_hash_operation_init();
+
+    status = psa_hash_setup(&op, PSA_ALG_SHA_256);
+    if (status != PSA_SUCCESS) return false;
+
+    status = psa_hash_update(&op, key_buf, key_len);
+    if (status != PSA_SUCCESS) return false;
+
+    status = psa_hash_finish(&op,
+        &instance->instance_id[1],
+        INSTANCE_ID_HASH_LEN,
+        &hash_len);
+
+    return (status == PSA_SUCCESS) && (hash_len == INSTANCE_ID_HASH_LEN);
+}
diff --git a/components/service/attestation/claims/sources/instance_id/instance_id_claim_source.h b/components/service/attestation/claims/sources/instance_id/instance_id_claim_source.h
new file mode 100644
index 0000000..e02ad5e
--- /dev/null
+++ b/components/service/attestation/claims/sources/instance_id/instance_id_claim_source.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef INSTANCE_ID_CLAIM_SOURCE_H
+#define INSTANCE_ID_CLAIM_SOURCE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <psa/crypto.h>
+#include <service/attestation/claims/claim_source.h>
+
+/* Instance ID defines */
+#define INSTANCE_ID_HASH_ALG        PSA_ALG_SHA_256
+#define INSTANCE_ID_HASH_LEN        PSA_HASH_SIZE(INSTANCE_ID_HASH_ALG)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A claim_source that provides an identifier for the device,
+ * comprising a hash of the IAK public key.
+ */
+struct instance_id_claim_source
+{
+    struct claim_source base;
+
+    bool is_known;
+
+    /* Space for the hashed key + a single type byte (see EAT) */
+    uint8_t instance_id[INSTANCE_ID_HASH_LEN + 1];
+};
+
+/**
+ * \brief Initializes a struct instance_id_claim_source
+ *
+ * \param[in] instance      The instance to initialze
+ *
+ * \return The initialize base claim_source structure
+ */
+struct claim_source *instance_id_claim_source_init(struct instance_id_claim_source *instance);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* INSTANCE_ID_CLAIM_SOURCE_H */
diff --git a/components/service/attestation/claims/sources/null_lifecycle/component.cmake b/components/service/attestation/claims/sources/null_lifecycle/component.cmake
new file mode 100644
index 0000000..a2ce3f2
--- /dev/null
+++ b/components/service/attestation/claims/sources/null_lifecycle/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/null_lifecycle_claim_source.c"
+	)
diff --git a/components/service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.c b/components/service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.c
new file mode 100644
index 0000000..add8bf9
--- /dev/null
+++ b/components/service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service/attestation/claims/claim.h>
+#include <psa/lifecycle.h>
+#include "null_lifecycle_claim_source.h"
+
+static bool null_lifecycle_claim_source_get_claim(void *context, struct claim *claim);
+
+
+struct claim_source *null_lifecycle_claim_source_init(struct null_lifecycle_claim_source *instance)
+{
+    instance->base.get_claim = null_lifecycle_claim_source_get_claim;
+    instance->base.context = instance;
+
+    return &instance->base;
+}
+
+static bool null_lifecycle_claim_source_get_claim(void *context, struct claim *claim)
+{
+    (void)context;
+
+    claim->category = CLAIM_CATEGORY_DEVICE;
+    claim->subject_id = CLAIM_SUBJECT_ID_LIFECYCLE_STATE;
+    claim->variant_id = CLAIM_VARIANT_ID_INTEGER;
+    claim->raw_data = NULL;
+
+    claim->variant.integer.value = PSA_LIFECYCLE_UNKNOWN;
+    return true;
+}
diff --git a/components/service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.h b/components/service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.h
new file mode 100644
index 0000000..4780c8c
--- /dev/null
+++ b/components/service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NULL_LIFECYCLE_CLAIM_SOURCE_H
+#define NULL_LIFECYCLE_CLAIM_SOURCE_H
+
+#include <service/attestation/claims/claim_source.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Use this claim source in deployments where there is no hardware
+ * backed support for a device's lifecycle state.  This claim
+ * source just returns a lifecycle state of 'unknown'.
+ */
+struct null_lifecycle_claim_source
+{
+    struct claim_source base;
+};
+
+/**
+ * \brief Initializes a struct null_lifecycle_claim_source
+ *
+ * \param[in] instance      The instance to initialze
+ *
+ * \return The initialize base claim_source structure
+ */
+struct claim_source *null_lifecycle_claim_source_init(
+    struct null_lifecycle_claim_source *instance);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* NULL_LIFECYCLE_CLAIM_SOURCE_H */
diff --git a/components/service/attestation/include/psa/lifecycle.h b/components/service/attestation/include/psa/lifecycle.h
new file mode 100644
index 0000000..02dcafa
--- /dev/null
+++ b/components/service/attestation/include/psa/lifecycle.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PSA_LIFECYCLE_H__
+#define __PSA_LIFECYCLE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PSA_LIFECYCLE_PSA_STATE_MASK            (0xff00u)
+#define PSA_LIFECYCLE_IMP_STATE_MASK            (0x00ffu)
+#define PSA_LIFECYCLE_UNKNOWN                   (0x0000u)
+#define PSA_LIFECYCLE_ASSEMBLY_AND_TEST         (0x1000u)
+#define PSA_LIFECYCLE_PSA_ROT_PROVISIONING      (0x2000u)
+#define PSA_LIFECYCLE_SECURED                   (0x3000u)
+#define PSA_LIFECYCLE_NON_PSA_ROT_DEBUG         (0x4000u)
+#define PSA_LIFECYCLE_RECOVERABLE_PSA_ROT_DEBUG (0x5000u)
+#define PSA_LIFECYCLE_DECOMMISSIONED            (0x6000u)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_LIFECYCLE_H__ */
diff --git a/components/service/attestation/key_mngr/attest_key_mngr.c b/components/service/attestation/key_mngr/attest_key_mngr.c
index 783d08f..cff1dcf 100644
--- a/components/service/attestation/key_mngr/attest_key_mngr.c
+++ b/components/service/attestation/key_mngr/attest_key_mngr.c
@@ -131,13 +131,18 @@
     return status;
 }
 
-size_t attest_key_mngr_max_iak_key_size(void)
+size_t attest_key_mngr_max_iak_export_size(void)
 {
     return PSA_KEY_EXPORT_MAX_SIZE(
         PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1)),
             IAK_KEY_BITS);
 }
 
+size_t attest_key_mngr_max_iak_import_size(void)
+{
+    return PSA_BITS_TO_BYTES(IAK_KEY_BITS);
+ }
+
 psa_status_t attest_key_mngr_import_iak(const uint8_t *data, size_t data_length)
 {
     psa_status_t status = PSA_ERROR_NOT_PERMITTED;
diff --git a/components/service/attestation/key_mngr/attest_key_mngr.h b/components/service/attestation/key_mngr/attest_key_mngr.h
index f61619a..0600be8 100644
--- a/components/service/attestation/key_mngr/attest_key_mngr.h
+++ b/components/service/attestation/key_mngr/attest_key_mngr.h
@@ -67,11 +67,18 @@
                                 size_t data_size, size_t *data_length);
 
 /**
- * \brief Return maximum size of an IAK key-pair
+ * \brief Return maximum size of an exported IAK public key
  *
- * \return Maximum size
+ * \return Maximum export size
  */
-size_t attest_key_mngr_max_iak_key_size(void);
+size_t attest_key_mngr_max_iak_export_size(void);
+
+/**
+ * \brief Return maximum size of an imported IAK key
+ *
+ * \return Maximum import size
+ */
+size_t attest_key_mngr_max_iak_import_size(void);
 
 /**
  * \brief Import the IAK key-pair
diff --git a/components/service/attestation/provider/attest_provider.c b/components/service/attestation/provider/attest_provider.c
index 460a6d0..9669ed6 100644
--- a/components/service/attestation/provider/attest_provider.c
+++ b/components/service/attestation/provider/attest_provider.c
@@ -168,7 +168,7 @@
 
     if (serializer) {
 
-        size_t max_key_size = attest_key_mngr_max_iak_key_size();
+        size_t max_key_size = attest_key_mngr_max_iak_export_size();
 
         uint8_t *key_buffer = malloc(max_key_size);
 
@@ -207,7 +207,7 @@
 
     if (serializer) {
 
-        size_t key_data_len = attest_key_mngr_max_iak_key_size();
+        size_t key_data_len = attest_key_mngr_max_iak_import_size();
         uint8_t *key_buffer = malloc(key_data_len);
 
         if (key_buffer) {
diff --git a/components/service/attestation/test/component/attestation_reporter_tests.cpp b/components/service/attestation/test/component/attestation_reporter_tests.cpp
index c83dc3c..984af99 100644
--- a/components/service/attestation/test/component/attestation_reporter_tests.cpp
+++ b/components/service/attestation/test/component/attestation_reporter_tests.cpp
@@ -5,18 +5,22 @@
  */
 
 #include <psa/error.h>
+#include <psa/crypto.h>
+#include <psa/lifecycle.h>
 #include <qcbor/qcbor_spiffy_decode.h>
 #include <t_cose/t_cose_sign1_verify.h>
 #include <service/attestation/claims/claims_register.h>
 #include <service/attestation/claims/sources/event_log/event_log_claim_source.h>
 #include <service/attestation/claims/sources/event_log/mock/mock_event_log.h>
-#include <service/attestation/claims/sources/preloaded/preloaded_claim_source.h>
+#include <service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.h>
+#include <service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.h>
+#include <service/attestation/claims/sources/instance_id/instance_id_claim_source.h>
 #include <service/attestation/reporter/attest_report.h>
 #include <service/attestation/key_mngr/attest_key_mngr.h>
 #include <service/attestation/test/common/report_dump.h>
 #include <protocols/service/attestation/packed-c/eat.h>
 #include <CppUTest/TestHarness.h>
-#include <psa/crypto.h>
+
 
 TEST_GROUP(AttestationReporterTests)
 {
@@ -36,10 +40,22 @@
          */
         claims_register_init();
 
-        /* Boot measurement source */
+        /* Boot measurement claim source */
         claim_source = event_log_claim_source_init(&event_log_claim_source,
             mock_event_log_start(), mock_event_log_size());
         claims_register_add_claim_source(CLAIM_CATEGORY_BOOT_MEASUREMENT, claim_source);
+
+        /* Boot seed claim source */
+        claim_source = boot_seed_generator_init(&boot_seed_claim_source);
+        claims_register_add_claim_source(CLAIM_CATEGORY_DEVICE, claim_source);
+
+        /* Lifecycle state claim source */
+        claim_source = null_lifecycle_claim_source_init(&lifecycle_claim_source);
+        claims_register_add_claim_source(CLAIM_CATEGORY_DEVICE, claim_source);
+
+        /* Instance ID claim source */
+        claim_source = instance_id_claim_source_init(&instance_id_claim_source);
+        claims_register_add_claim_source(CLAIM_CATEGORY_DEVICE, claim_source);
     }
 
     void teardown()
@@ -50,6 +66,9 @@
     }
 
     struct event_log_claim_source event_log_claim_source;
+    struct boot_seed_generator boot_seed_claim_source;
+    struct null_lifecycle_claim_source lifecycle_claim_source;
+    struct instance_id_claim_source instance_id_claim_source;
     const uint8_t *report;
     size_t report_len;
 };
@@ -126,6 +145,36 @@
     UNSIGNED_LONGS_EQUAL(sizeof(auth_challenge), auth_challenge_buf.len);
     MEMCMP_EQUAL(auth_challenge, auth_challenge_buf.ptr, sizeof(auth_challenge));
 
+    /* Check the boot seed */
+    UsefulBufC boot_seed_buf;
+    boot_seed_buf.ptr = NULL;
+    boot_seed_buf.len = 0;
+    QCBORDecode_GetByteStringInMapN(&decode_ctx,
+        EAT_ARM_PSA_CLAIM_ID_BOOT_SEED, &boot_seed_buf);
+
+    LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+    CHECK_TRUE(boot_seed_buf.ptr);
+    UNSIGNED_LONGS_EQUAL(sizeof(boot_seed_claim_source.boot_seed), boot_seed_buf.len);
+
+    /* Check the lifecycle state */
+    int64_t decoded_lifecycle_state = 0;
+    QCBORDecode_GetInt64InMapN(&decode_ctx,
+        EAT_ARM_PSA_CLAIM_ID_SECURITY_LIFECYCLE, &decoded_lifecycle_state);
+
+    LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+    LONGS_EQUAL(PSA_LIFECYCLE_UNKNOWN, decoded_lifecycle_state);
+
+    /* Check the instance ID */
+    UsefulBufC instance_id_buf;
+    instance_id_buf.ptr = NULL;
+    instance_id_buf.len = 0;
+    QCBORDecode_GetByteStringInMapN(&decode_ctx,
+        EAT_ARM_PSA_CLAIM_ID_INSTANCE_ID, &instance_id_buf);
+
+    LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+    CHECK_TRUE(instance_id_buf.ptr);
+    UNSIGNED_LONGS_EQUAL(sizeof(instance_id_claim_source.instance_id), instance_id_buf.len);
+
     /* Shouldn't expect to see the 'NO_SW_COMPONENTS' claim */
     int64_t no_sw = 0;
     QCBORDecode_GetInt64InMapN(&decode_ctx, EAT_ARM_PSA_CLAIM_ID_NO_SW_COMPONENTS, &no_sw);
diff --git a/components/service/locator/standalone/services/attestation/attestation_service_context.cpp b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
index 302a536..c23bf5c 100644
--- a/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
+++ b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
@@ -13,7 +13,10 @@
 attestation_service_context::attestation_service_context(const char *sn) :
     standalone_service_context(sn),
     m_attest_provider(),
-    m_event_log_claim_source()
+    m_event_log_claim_source(),
+    m_boot_seed_claim_source(),
+    m_lifecycle_claim_source(),
+    m_instance_id_claim_source()
 {
 
 }
@@ -36,11 +39,23 @@
      */
     claims_register_init();
 
-    /* Boot measurement source - uses mock event log */
+    /* Boot measurement claim source - uses mock event log */
     claim_source = event_log_claim_source_init(&m_event_log_claim_source,
         mock_event_log_start(), mock_event_log_size());
     claims_register_add_claim_source(CLAIM_CATEGORY_BOOT_MEASUREMENT, claim_source);
 
+    /* Boot seed claim source */
+    claim_source = boot_seed_generator_init(&m_boot_seed_claim_source);
+    claims_register_add_claim_source(CLAIM_CATEGORY_DEVICE, claim_source);
+
+    /* Lifecycle state claim source */
+    claim_source = null_lifecycle_claim_source_init(&m_lifecycle_claim_source);
+    claims_register_add_claim_source(CLAIM_CATEGORY_DEVICE, claim_source);
+
+    /* Instance ID claim source */
+    claim_source = instance_id_claim_source_init(&m_instance_id_claim_source);
+    claims_register_add_claim_source(CLAIM_CATEGORY_DEVICE, claim_source);
+
     /* Initialize the attestation service provider */
     struct rpc_interface *attest_ep =
         attest_provider_init(&m_attest_provider, ATTEST_KEY_MNGR_VOLATILE_IAK);
diff --git a/components/service/locator/standalone/services/attestation/attestation_service_context.h b/components/service/locator/standalone/services/attestation/attestation_service_context.h
index ad8d0ee..8ccd938 100644
--- a/components/service/locator/standalone/services/attestation/attestation_service_context.h
+++ b/components/service/locator/standalone/services/attestation/attestation_service_context.h
@@ -11,7 +11,9 @@
 #include <rpc/direct/direct_caller.h>
 #include <service/attestation/provider/attest_provider.h>
 #include <service/attestation/claims/sources/event_log/event_log_claim_source.h>
-
+#include <service/attestation/claims/sources/boot_seed_generator/boot_seed_generator.h>
+#include <service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.h>
+#include <service/attestation/claims/sources/instance_id/instance_id_claim_source.h>
 
 class attestation_service_context : public standalone_service_context
 {
@@ -26,6 +28,9 @@
 
     struct attest_provider m_attest_provider;
     struct event_log_claim_source m_event_log_claim_source;
+    struct boot_seed_generator m_boot_seed_claim_source;
+    struct null_lifecycle_claim_source m_lifecycle_claim_source;
+    struct instance_id_claim_source m_instance_id_claim_source;
 };
 
 #endif /* STANDALONE_ATTESTATION_SERVICE_CONTEXT_H */
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index a4ee13e..2a8556a 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -44,7 +44,9 @@
 		"components/service/locator/standalone/services/attestation"
 		"components/service/attestation/include"
 		"components/service/attestation/claims"
-		"components/service/attestation/claims/sources/preloaded"
+		"components/service/attestation/claims/sources/boot_seed_generator"
+		"components/service/attestation/claims/sources/null_lifecycle"
+		"components/service/attestation/claims/sources/instance_id"
 		"components/service/attestation/claims/sources/event_log"
 		"components/service/attestation/claims/sources/event_log/mock"
 		"components/service/attestation/claims/sources/event_log/test"
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index d1a96ae..842f702 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -43,7 +43,9 @@
 		"components/service/locator/standalone/services/attestation"
 		"components/service/attestation/include"
 		"components/service/attestation/claims"
-		"components/service/attestation/claims/sources/preloaded"
+		"components/service/attestation/claims/sources/boot_seed_generator"
+		"components/service/attestation/claims/sources/null_lifecycle"
+		"components/service/attestation/claims/sources/instance_id"
 		"components/service/attestation/claims/sources/event_log"
 		"components/service/attestation/claims/sources/event_log/mock"
 		"components/service/attestation/reporter/psa"