Skip to content

fix: generate the provision key before loading the sign key#27

Merged
MathiasKoch merged 1 commit into
masterfrom
fix/flush-sign-key-before-keygen
Jul 1, 2026
Merged

fix: generate the provision key before loading the sign key#27
MathiasKoch merged 1 commit into
masterfrom
fix/flush-sign-key-before-keygen

Conversation

@MathiasKoch

Copy link
Copy Markdown
Member

Summary

Fleet provisioning fails at the CSR-flow key generation on TPMs with the spec-minimum ~3 transient object slots (swtpm, Infineon SLB9670):

Esys_CreateLoaded ErrorCode (0x00000902) -> tpm:warn: out of memory for object contexts
Failed to generate key pair

Root cause (measured, not guessed)

tpm2-pkcs11 keeps a key loaded (cached) after an operation and only flushes it on C_DestroyObject — which never happens for a token key. An strace of the TPM command stream shows Load; Sign for the sign key with no following FlushContext, then CreateLoaded fails.

A tpm2-pytss harness pinned it down exactly:

  • one PKCS#11/RM connection holds at most 3 transient objects;
  • the keygen tolerates the sobject + 1 cached child; a 2nd cached child tips CreateLoaded over (4 > 3);
  • the kernel resource manager virtualises objects per connection, so the claim key on the separate aws-crt Pkcs11Lib connection is not the problem — it's the sign key, cached on the same SunPKCS11 connection that then runs keygen.

Fix

Generate the provision key up front, while the SunPKCS11/TPM connection is clean, before the authorizer signature loads the sign key. CreateLoaded then runs with only the sobject loaded, well within budget. Every later step (sign, CSR sign) only loads keys (no create), so they stay within the 3-slot ceiling.

No tpm2-pkcs11 change, no flush plumbing, no reliance on GC/finalize timing — just do the one object-creating operation when nothing else is cached.

Validation

To be confirmed on hardware/QEMU: after this change the strace should show the provision key's CreateLoaded succeeding early, and the sign Load; Sign happening afterwards within the 3-slot budget.

On a TPM with the spec-minimum ~3 transient object slots (swtpm, Infineon
SLB9670), fleet provisioning failed at the CSR-flow key generation with
TPM_RC_OBJECT_MEMORY (0x902): tpm2-pkcs11 keeps a key loaded (cached) after use
and only flushes it on C_DestroyObject, which never happens for a token key.

Instrumentation (strace of the TPM command stream + a tpm2-pytss harness)
showed the keygen's PKCS#11 connection can hold at most one cached child key
alongside the sobject before TPM2_CreateLoaded runs out of slots. Because the
authorizer signature (sign the clientId with the sign key) runs first on the
same SunPKCS11 connection, the sign key is still cached when the provision key
is generated, so CreateLoaded has no room.

The kernel resource manager virtualises transient objects per connection, so
the claim key on the separate aws-crt Pkcs11Lib connection is not involved.

Fix: generate the provision key up front, while the connection is clean,
before the sign key is loaded. No library change and no flush plumbing — the
one object-creating operation runs when nothing else is cached.
@MathiasKoch
MathiasKoch merged commit 818e3f6 into master Jul 1, 2026
1 check passed
@MathiasKoch
MathiasKoch deleted the fix/flush-sign-key-before-keygen branch July 1, 2026 10:02
@MathiasKoch
MathiasKoch restored the fix/flush-sign-key-before-keygen branch July 1, 2026 11:48
@MathiasKoch
MathiasKoch deleted the fix/flush-sign-key-before-keygen branch July 1, 2026 11:50
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.

1 participant