Skip to content

Conversation

@sahesaha
Copy link

@sahesaha sahesaha commented Nov 3, 2025

Add code to block destroy operations on objects
marked CKA_INDESTRUCTIBLE. This ensures token objects flagged as indestructible cannot be deleted or modified by normal operations.

Tested by creating an indestructible object in the TA and verifying destroy/modify calls return proper code.

Reviewed-by: Neeraj Soni neersoni@qti.qualcomm.com
Tested on: SM7325 SoC
Signed-off-by: Saheli Saha sahesaha@qti.qualcomm.com

@jforissier
Copy link
Contributor

Hi @sahesaha, there is a mistake here, you added a patch file instead of modifying the source files themselves.

@sahesaha sahesaha force-pushed the Indestructible_token-objects branch from e39c3e5 to fcd2203 Compare November 3, 2025 09:12
@sahesaha
Copy link
Author

sahesaha commented Nov 3, 2025

Hi @jforissier, could you please check now? I have removed the patch file from the commit.

@Emantor
Copy link
Contributor

Emantor commented Nov 3, 2025

Since this is not contained in the PKCS11 specification, this is a vendor extension that I am not sure we want to support. Do other PKCS11 implementations implement something similar? What exactly do you use this extension for?

@sahesaha sahesaha force-pushed the Indestructible_token-objects branch from fcd2203 to 3f99281 Compare November 3, 2025 13:10
@sahesaha
Copy link
Author

sahesaha commented Nov 3, 2025

Hi @Emantor, the use case is to stop some objects from getting destroyed even if C_Destroy is called on them and to prevent destruction of token objects on reinitialization if they are declared CKA_INDESTRUCTIBLE, a tamper detection key can be an example which is provisioned during factory setting and needs to be persisted even after C_Destroy call.

The test cases designed to validate these changes will be raised soon in optee_test repo.

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, the PKCS#11 allows to token to not destroy some objects. Using a vendor attribute for that looks ok to me. Maybe this should be under a TA config switch (CFG_PKCS11_TA_INDESTRUCTIBLE_OBJECT=y|n).

0x0600,

/* Vendor specific attributes */
PKCS11_CKA_INDESTRUCTIBLE = 0x80000010,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer have this listed below, next to PKCS11_CKA_OPTEE_HIDDEN_EC_POINT definition and use ID 0x0001 | (1<<31) for consisteny of the IDs of OP-TEE vendor specific attribute IDs.
Also, using OPTEE_ prefix would better highlight across the implementation that it's a custom ID.

Suggested change
PKCS11_CKA_INDESTRUCTIBLE = 0x80000010,
PKCS11_CKA_OPTEE_INDESTRUCTIBLE = PKCS11_CKA_VENDOR_DEFINED |
0x0001,

/* Try twice otherwise panic! */
if (unregister_persistent_object(token, obj->uuid) &&
unregister_persistent_object(token, obj->uuid))
unregister_persistent_object(token, obj->uuid))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discard this change. Previous indentation was fine.


if (get_bool(obj->attributes, PKCS11_CKA_INDESTRUCTIBLE)) {
// Skip deletion for indestructible objects
LIST_REMOVE(obj, link);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need a bit more. obj volatile resources should be freed.
I would suggest to use cleanup_volatile_obj_ref() from object.c.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expectation of the implementation is that the INDETSRUCTIBLE objects should persist in the persistent_storage even after reinit. So, we need not call cleanup_volatile_obj_ref().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the token in re-initialized, the object would still remain loaded in memory.
Calling cleanup_volatile_obj_ref() would release RAM from object resources but the object would still remain in the persistent database and be re-loaded only once it's used.

* Check if the indestructible attribute of a to-be-created
* object is present only if it is a token object
*/
enum pkcs11_rc check_indestructible_access(struct pkcs11_session *session,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sanity test could rather be part of check_attrs_misc_integrity().
I think an object with this attribute should also have attribute CKA_DESTROYABLE to false, for consistency. This should be also checked in check_attrs_misc_integrity().


/* Objects with PKCS11_CKA_INDESTRUCTIBLE as true aren't destroyable */
if (get_bool(object->attributes, PKCS11_CKA_INDESTRUCTIBLE)) {
SLogTrace("Object is indestructible");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EMSG(). That said, PKCS11_CKA_DESTROYABLE above should have done the job.

}

if (!obj->attributes) {
return PKCS11_CKR_OBJECT_HANDLE_INVALID;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed?

uint32_t pin_size = 0;
void *pin = NULL;
struct pkcs11_object *obj = NULL;
struct pkcs11_object *tvar = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove?

@github-actions
Copy link

github-actions bot commented Dec 7, 2025

This pull request has been marked as a stale pull request because it has been open (more than) 30 days with no activity. Remove the stale label or add a comment, otherwise this pull request will automatically be closed in 5 days. Note, that you can always re-open a closed issue at any time.

@github-actions github-actions bot added the Stale label Dec 7, 2025
@sahesaha
Copy link
Author

sahesaha commented Dec 8, 2025

Commenting to keep alive.

@sahesaha sahesaha force-pushed the Indestructible_token-objects branch from 3f99281 to 2fdb17c Compare December 13, 2025 20:45
@sahesaha
Copy link
Author

@etienne-lms, please review the latest changes. The comments have been addressed.

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. Please find my review comments together with, again, my apologies.

DMSG("CKA_INDESTRUCTIBLE not present in template");
} else {
/* Attribute exists, get its value (TRUE or FALSE) */
bool indestructible = get_bool(temp, PKCS11_CKA_OPTEE_INDESTRUCTIBLE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: could you add an empty line below this local variable definition?


/* Add attribute with the actual value from template */
rc = add_attribute(&attrs, PKCS11_CKA_OPTEE_INDESTRUCTIBLE,
&indestructible, sizeof(indestructible));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking on indentation:

Suggested change
&indestructible, sizeof(indestructible));
&indestructible, sizeof(indestructible));

enum pkcs11_rc rc_check = get_attribute_ptr(temp, PKCS11_CKA_OPTEE_INDESTRUCTIBLE, NULL, NULL);

if (rc_check == PKCS11_RV_NOT_FOUND) {
DMSG("CKA_INDESTRUCTIBLE not present in template");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you be ok to discard this debug message?

Comment on lines 1550 to 1553
/*
* Check if the indestructible attribute of a to-be-created
* object is present only if it is a token object
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test actually checks if the boolean attribute is set, not present (allowed to be present and disabled), which looks fine to me.

Suggested change
/*
* Check if the indestructible attribute of a to-be-created
* object is present only if it is a token object
*/
/* Only token objects can be indestructible */

[BPA_DESTROYABLE] = PKCS11_CKA_DESTROYABLE,
[BPA_ALWAYS_AUTHENTICATE] = PKCS11_CKA_ALWAYS_AUTHENTICATE,
[BPA_WRAP_WITH_TRUSTED] = PKCS11_CKA_WRAP_WITH_TRUSTED,
[BPA_INDESTRUCTIBLE] = PKCS11_CKA_OPTEE_INDESTRUCTIBLE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking, for consistency with indentaion above:

Suggested change
[BPA_INDESTRUCTIBLE] = PKCS11_CKA_OPTEE_INDESTRUCTIBLE,
[BPA_INDESTRUCTIBLE] = PKCS11_CKA_OPTEE_INDESTRUCTIBLE,

Comment on lines 991 to 995
/* Ensure that only token objects can be indestructible */
rc = check_attrs_misc_integrity(head);
if (rc)
goto out;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed, this is already addressed by the calls to check_created_attrs_against_token() above.

enum pkcs11_rc check_created_attrs(struct obj_attrs *key1,
struct obj_attrs *key2);

enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this helper function can remain local to pkcs11_atrtibutes.c.


if (get_bool(obj->attributes, PKCS11_CKA_INDESTRUCTIBLE)) {
// Skip deletion for indestructible objects
LIST_REMOVE(obj, link);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the token in re-initialized, the object would still remain loaded in memory.
Calling cleanup_volatile_obj_ref() would release RAM from object resources but the object would still remain in the persistent database and be re-loaded only once it's used.

TEE_Panic(0);

cleanup_persistent_object(obj, token);
token_invalidate_object_handles(obj);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleanup_persistent_object() frees obj pointer so token_invalidate_object_handles() here will not do anything.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I retained token_invalidate_object_handles(obj) because cleanup_persistent_object() only frees the object memory and does not invalidate the open handles associated with it as I tested some pointers were still remaining after cleanup-persistent_object() call. I was following the sequence observed in the destroy_object definition where both calls are present.

goto out;

/* Ensure that only token objects can be indestructible */
rc = check_attrs_misc_integrity(head);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed, this is already addressed by the calls to check_created_attrs_against_token() above.

@etienne-lms
Copy link
Contributor

I'd prefer you also introduce a config switch to enable this feature. Some PKCS#11 token may not expect a user can create such indestructible objects. Something like CFG_PKCS11_TA_INDESTRUCTIBLE_OBJECT_ATTR=y|n.

@sahesaha sahesaha force-pushed the Indestructible_token-objects branch 3 times, most recently from de084d3 to d15ecdf Compare January 9, 2026 10:26
@sahesaha
Copy link
Author

sahesaha commented Jan 9, 2026

Hi @etienne-lms, regarding your concern of config switch and controlled compilation, I understand the concern about the persistent database growing if these objects are created unchecked. However, I believe a compile-time switch (CFG_PKCS11_TA_TEST_...) is not the best approach for a few reasons:

Production Utility: Indestructible objects are not just for testing; they are needed for factory-provisioned items (like device attestation keys) that should persist for the device's lifetime and be protected from accidental deletion by the rich OS. A test-only switch would disable this valid use case.
Opt-In Safety: The feature is completely dormant unless the CKA_INDESTRUCTIBLE attribute is explicitly set. Standard applications won't accidentally trigger this.

Also, the rest of the comments are addressed in the latest commit. Please let me know your reviews.

The template for INDESTRUCTIBLE objects have CKA_TOKEN=true.

Added code to block destroy operations on objects
marked CKA_INDESTRUCTIBLE. This ensures token objects flagged as
indestructible cannot be deleted or modified by normal operations.

The expectation of the implementation of this vendor defined
attribute "INDESTRUCTIBLE" is that, the indestructible objects would
persist in persistent_storage after reinit or destroy call.

Tested by creating an indestructible object in the TA and verifying
destroy/modify calls return proper code.

Reviewed-by: Neeraj Soni <neersoni@qti.qualcomm.com>
Tested on: SM7325 SoC
Signed-off-by: Saheli Saha <sahesaha@qti.qualcomm.com>
@sahesaha sahesaha force-pushed the Indestructible_token-objects branch from d15ecdf to b88a9e4 Compare January 9, 2026 10:34
@etienne-lms
Copy link
Contributor

However, I believe a compile-time switch (CFG_PKCS11_TA_TEST_...) is not the best approach for a few reasons:

In OP-TEE OS, I propose to add a config switch only to enable (or not) indestructible object support in the pkcs11 TA:
CFG_PKCS11_TA_INDESTRUCTIBLE_OBJECT_ATTR.
I think it should be default disabled, but you are free to default enable it for your platform and/or from your product build environment.

In OP-TEE Test P-R (OP-TEE/optee_test#803) I proposed another switch, to embedded or the tests that creates these indestructible objects.
CFG_PKCS11_TA_TEST_INDESTRUCTIBLE_OBJECT_ATTR. (maybe another name would be better :-)
Thinking twice, I guest such switch could be useless if xtest was not creating its indestructible test object if it find it's always the test could simple try to destroy it and check it can't. But let's discuss this in P-R OP-TEE/optee_test#803.

By the way, please update the commit message header to start with ta: pkcs11: , e.g.:
ta: pkcs11: add indestructible objects attribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants