Audit the attributes, not the datasheet.

Research

7 min read

PKCS #11 POLICY

The policy behind the handle is readable, and almost nobody reads it.

The earlier article argued that a PKCS #11 handle tells an application nothing about what the key behind it is permitted to do. That is a design observation. This one is about the consequence: the permissions are sitting in the token right now, queryable, and many organisations have never enumerated them.

A first attribute inventory can often be produced in an afternoon, without downtime and using the same logical access already available to the application. Establishing provenance and evaluating every mechanism may take considerably longer.

The measurement that should still be uncomfortable

In 2010, Bortolozzo, Centenaro, Focardi and Steel presented Tookan at ACM CCS. The tool reverse-engineers a token’s actual capabilities, builds a model of its API, runs a model checker against it, and executes any attack trace the checker finds directly on the device.

They tested seventeen commercially available tokens.

Nine were vulnerable to key extraction. The other eight had severely restricted functionality. Not one device was both secure and fully functional. Attacks on the vulnerable devices were usually found in seconds.

These were tamper-resistant devices sold on the strength of their certifications. One vendor registered a CVE (CVE-2010-3321); most responses were minimal. The authors noted that they had hoped to encounter tokens patched against known attacks and instead found simple flaws or minimal functionality.

Sixteen years later, this study has not been systematically repeated in public.

Why the attacks work

PKCS #11 expresses a key’s role through attributes. The standard permits attribute combinations that contradict each other, and the contradiction is exploitable in one step.

The canonical case is a key with both CKA_WRAP and CKA_DECRYPT, combined with compatible mechanisms and access to the relevant objects.

Wrapping means encrypting one key under another. Decryption means recovering plaintext from ciphertext. If the same key can do both, the attacker calls C_WrapKey to wrap the sensitive key under it, then calls C_Decrypt on the result. The token performs both operations willingly, because each is individually permitted, and the sensitive key leaves in cleartext.

The symmetric case is a key with both CKA_UNWRAP and CKA_ENCRYPT, which allows importing a chosen key value.

There is a simpler variant the model checker found and which had not previously appeared in the literature: if the token permits C_CreateObject, the attacker imports a wrapping key whose value they already know, wraps the sensitive key under it, and decrypts the result off the device. No cryptographic weakness is involved anywhere. The token followed its own rules.

The two attributes that describe the past

Most PKCS #11 attributes describe the current state. Two describe history, and they are the reason the audit is worth running rather than assuming.

CKA_SENSITIVE and CKA_EXTRACTABLE are sticky in one direction each: sensitive can be turned on but not off, extractable can be turned off but not on. This gives the impression that a key marked sensitive and non-extractable has always been protected.

It has not necessarily.

CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE are maintained by the token and describe whether the key has continuously satisfied the corresponding protections since creation. A key showing CKA_SENSITIVE = true and CKA_ALWAYS_SENSITIVE = false does not carry evidence that it has always been sensitive.

That combination is not proof of disclosure. It is proof that the current flags do not establish continuous protection.

It can also be the expected signature of a key that was generated outside the token and imported during a migration, a disaster-recovery test, a vendor change or an initial provisioning that predates current staff. In that case the value existed somewhere else. Whether it still does is a question the token cannot answer.

The rules to evaluate

The audit is a set of predicates over the attribute table. Each one is a yes-or-no question with an unambiguous answer.

Role separation

  1. No key has both CKA_WRAP and CKA_DECRYPT.
  2. No key has both CKA_UNWRAP and CKA_ENCRYPT.
  3. Any key with both CKA_SIGN and CKA_UNWRAP has a documented need, with the permitted mechanisms reviewed for cross-role abuse.
  4. Any key with CKA_DERIVE has a constrained derivation template that prevents derived material from becoming exportable contrary to policy.

Extraction

  1. Every long-term key has CKA_EXTRACTABLE = false, or CKA_WRAP_WITH_TRUSTED = true with a wrapping key that is itself CKA_TRUSTED, non-extractable, and generated on-device.
  2. Every long-term key has CKA_ALWAYS_SENSITIVE = true and CKA_NEVER_EXTRACTABLE = true, unless its documented lifecycle explains otherwise. Any exception is a provenance question to investigate, not a finding to accept silently.

Import surface

  1. C_CreateObject is unavailable to the application’s role, or restricted to public objects.
  2. CKA_MODIFIABLE = false on production keys.
  3. CKA_PRIVATE = true and CKA_TOKEN = true where persistence and authentication are intended.

The question the attributes cannot answer

  1. What administrative paths exist outside the PKCS #11 interface? Most HSM vendors provide backup, cloning and restore tooling that moves key material without setting CKA_EXTRACTABLE. Those paths are legitimate and necessary. They are also a key-export mechanism that your attribute audit will not see, and the custody controls around them are usually weaker than the ones around the cryptographic interface. Ask the vendor to document them explicitly and in writing.

Running it

pkcs11-tool from OpenSC enumerates objects and attributes on most tokens. The commercial vendors ship equivalents. The procedure:

  1. C_FindObjects with an empty template to enumerate every object in every slot the application can see.
  2. C_GetAttributeValue per object for the attribute set above. Attributes that return CKR_ATTRIBUTE_SENSITIVE are themselves information. Record the error, not just the absence.
  3. Emit one row per key.
  4. Evaluate the predicates.
  5. For every key, name the application that uses it and the ceremony record that created it.

Step five is where the exercise usually stops, and stopping there is the finding. A key whose attributes are correct but whose origin nobody can account for is not in a better position than a key with the wrong attributes; it is in a worse one, because the attributes have created confidence that the provenance does not support.

The inventory that should exist

One row per key, with: label, ID, object class, key type, size, slot, the ten attributes above, creation date, generated-on-device or imported, the ceremony or change record, the owning application, the intended retirement date, and the algorithm-migration status.

Most organisations with HSMs cannot produce this table on request. Producing it is the deliverable, and it is worth more than the audit predicates, because it is the artefact that makes the next migration possible. The post-quantum transition will require knowing which keys exist, what they sign, how long their signatures must remain verifiable, and which of them are pinned into devices that cannot be updated. That is the same table.

What certification did and did not cover

Some devices in the Tookan study were marketed with FIPS or Common Criteria certification claims. Such certifications are neither fraudulent nor irrelevant. They evaluate a defined module or product against a stated boundary, security target and assurance process.

They do not, by themselves, evaluate the attribute configuration in a particular production slot. That configuration is created by provisioning scripts, migrations, operational ceremonies and administrative decisions made after the product evaluation.

The certification is a statement about the product. The audit is a statement about your deployment. Only one of them is specific to you, and only one of them is currently unwritten.

Open work, with impact

The most valuable project in this area is also the most obvious one, and it has been available for sixteen years.

Repeat the Tookan study on current devices. The methodology is published in full. The tool’s design is described in the paper. The device population has turned over completely: cloud HSM services, PKCS #11 implementations layered over KMS APIs, software tokens in containers, and secure elements in phones now sit where USB tokens sat in 2010. Nobody appears to have published a systematic result on any of them.

Specific questions that would matter:

  1. Do cloud HSM offerings that expose a PKCS #11 interface enforce role separation, or do they inherit the standard’s permissiveness?
  2. Do PKCS #11 shims over cloud KMS APIs preserve attribute semantics, or silently accept attributes they cannot enforce?
  3. How do current tokens behave on the C_CreateObject variant, which was novel in 2010 and is now well known?
  4. What fraction of production keys in a real deployment show CKA_ALWAYS_SENSITIVE = false? This is measurable by any organisation on its own estate and, as far as we can determine, has never been reported in aggregate.

The fourth question requires no research budget at all. It requires someone to run the query.


References

  1. Bortolozzo M, Centenaro M, Focardi R, Steel G (2010). Attacking and Fixing PKCS#11 Security Tokens. ACM CCS ’10
  2. Tookan project page, Secgroup, Università Ca’ Foscari
  3. PKCS #11 Cryptographic Token Interface Base Specification, OASIS
  4. OpenSC project, including pkcs11-tool
  5. FIPS 140-3: Security Requirements for Cryptographic Modules

Related Articles

Two embossed paper strips emerging from a precision press while a magnifier reveals their surface detail.

Sign the same message twice.

Repeated signing reveals whether output varies. Across a population, repeated ECDSA values can expose nonce reuse, compromise and implementation anomalies.