Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Étude — Keyring kernel Linux vs fichier 0600 + air-keysign, pour le matériel privé du keystore

Statut : note d’étude (exploration, ne tranche rien — 2026-07-30). Répond à la question « la couche 0 devrait-elle wrapper add_key/request_key/keyctl, et Air devrait-il stocker le matériel privé dans le keyring kernel plutôt qu’en fichier scellé 0600 + courtier air-keysign ? ». Contexte : idée parquée d’un keystore système multi-owner ([mémoire], services non-root sans home) et protection au repos différée (ADR-108 §2).

1. Ce qu’est le keyring kernel (rappel factuel)

Un service noyau de stockage de clés en mémoire avec ACL appliquée par le kernel :

  • Trousseaux hiérarchiques : thread / process / session / user / user-session / persistent (par-uid) / nommés. Un process « possède » une clé si elle est liée dans l’un de ses trousseaux (sémantique de possession, distincte du propriétaire uid/gid).
  • Permissions par clé : possessor/user/group/other × view/read/write/search/link/setattr,
    • chown/setperm/set_timeout. Contrôle d’accès kernel, pas filesystem.
  • Types de clés :
    • user — blob opaque relisible par userspace (≤ ~32 KiB) ;
    • logon — comme user mais non relisible depuis userspace (readback bloqué) ; seuls des consommateurs noyau (dm-crypt, fscrypt, NFS/CIFS…) le récupèrent ;
    • asymmetric — clé asymétrique ; peut exposer KEYCTL_PKEY_{SIGN,VERIFY,ENCRYPT,DECRYPT} sans livrer la clé, si le sous-type et l’algo sont supportés par l’akcipher noyau ;
    • trusted / encryptedscellées par un TPM (la clé n’est jamais en clair sur disque) ;
    • keyring, big_key.
  • Syscalls : add_key(2), request_key(2) (+ upcall d’instanciation à la demande), keyctl(2) (add/update/read/revoke/search/link/setperm/chown/timeout/pkey_*…).

2. La contrainte décisive pour Air : signer de l’Ed25519 sans exposer la clé

Le besoin structurant d’Air (SSH) est l’émission/signature Ed25519 oracle-safe : un service non-root obtient une signature sans jamais détenir la graine.

  • Le seul type de keyring qui signe sans livrer la clé est asymmetric via KEYCTL_PKEY_SIGN. Or le support akcipher logiciel du noyau vise historiquement RSA/ECDSA (signature de modules, IMA) ; le support Ed25519 pour KEYCTL_PKEY_SIGN n’est pas portablement garanti (dépend de CONFIG_*, de la version, du parseur pkcs8). À vérifier sur le kernel cible — mais on ne peut pas s’appuyer dessus pour une brique fondatrice validée jusqu’au Pi 4.
  • logon protège le readback mais n’est utilisable que par le noyau — pas de signature SSH userspace possible.
  • user est relisible ⇒ le service détiendrait la graine ⇒ fuite à la compromission : exactement ce que le privsep/air-keysign combat.

Conséquence : pour l’Ed25519 SSH, le keyring ne fournit pas « signer sans exposer ». air-keysign (courtier userspace privilégié, ADR-108 §5), lui, le fait pour n’importe quel algorithme (dont Ed25519), avec notre crypto Rust ([doctrine-sourcing-crypto]), en validant la structure et en restreignant l’appelant (peer credentials). Sur le cœur du besoin, air-keysign gagne.

3. Deux limites structurelles du keyring comme « stockage »

  1. Éphémère. Les trousseaux meurent avec leur session/process ; le trousseau persistent (par-uid) survit à la déconnexion mais est récupéré après un délai sans session active. Le keyring est donc un cache runtime, pas un système de référence durable. Un magasin fichier reste nécessaire pour recharger au boot. Le keyring ne remplace pas les *.aircfg.
  2. Crypto/scellé = du C noyau. La signature asymmetric et le scellé trusted/encrypted reposent sur le crypto noyau (C) et, pour le scellé, sur un TPM (pile C tpm2). Cela heurte la doctrine pur-Rust / C-free ([doctrine-sourcing-crypto]) et le TPM n’existe pas sur tous les cibles d’Air (Pi 4). Les clés trusted ne sont donc pas universellement disponibles.

4. Comparaison par dimension

DimensionKeyring kernelFichier 0600 scellé + air-keysign
Signer Ed25519 sans exposer la clé✗ (akcipher Ed25519 non portable ; logon = noyau only ; user = fuite)✅ courtier, tout algo, notre crypto Rust
Contrôle d’accès multi-owner✅ ACL kernel par-clé (uid/gid/perms/possession)✅ le courtier applique l’ACL (owner/shared) + peer creds
Protection au repos✅✅ trusted/encrypted scellé TPM (jamais en clair) — si TPM⚠️ aujourd’hui 0600 clair (Argon2 différé ADR-108 §2)
Durabilité (référence)✗ éphémère (cache runtime)✅ fichier = système de référence
Doctrine pur-Rust / C-free✗ crypto/scellé = C noyau + TPM C✅ notre stack Rust
Universalité matériel (jusqu’au Pi 4)⚠️ dépend CONFIG_* ; TPM absent sur Pi✅ partout
Alimenter un consommateur NOYAU (fscrypt/dm-crypt)✅✅ seul mécanisme (via logon/encrypted)✗ non concerné

5. Là où le keyring est réellement le bon outil (drivers futurs légitimes)

Le keyring n’est pas le bon véhicule pour la signature SSH, mais il l’est pour :

  • Chiffrement au repos adossé au TPM : sur une machine avec TPM, sceller les magasins d’Air (ou une clé maître Argon2) par une clé trusted/encrypted donne un « jamais en clair sur disque » que le fichier 0600 n’offre pas. Optionnel, matériel-dépendant — un durcissement, pas un socle.
  • Consommateurs noyau : si Air adopte un jour fscrypt (répertoire keystore chiffré) ou dm-crypt, la clé doit transiter par le keyring (logon/encrypted) — c’est l’unique interface. C’est le driver le plus solide pour, alors, wrapper add_key/request_key/keyctl.

6. Recommandation

  1. Mécanisme primaire du matériel privé = air-keysign (déjà contractualisé ADR-108 §5) + magasins fichier 0600 comme référence durable. Il résout à la fois l’ACL multi-owner et le « ne jamais livrer la clé », pour tout algorithme, en Rust. C’est aussi la réponse à la tension de l’idée parquée (services non-root) : ils passent par le courtier, pas par une lecture directe.
  2. Keyring = complément optionnel, différé. Garder keyctl/add_key/request_key en « à évaluer » dans UNSUPPORTED.md et family-security, priorité basse. Ne les wrapper en couche 0 que lorsqu’un consommateur concret existe : (a) un durcissement at-rest TPM conçu, ou (b) l’adoption fscrypt/dm-crypt. Le faire « au cas où » violerait « optimiser après mesure » (Principe 5) et ajouterait de la surface non consommée.
  3. Si/quand on l’attaque : suivre le motif Landlock/seccomp — couche 0 primitive (wrappers typés Result<_, Errno>, fuzz sur ce qui parse de l’externe), API déclarative en couche 1, intégration keystore en couche 2. Un ADR dédié (amende ADR-108) au moment venu.

En une phrase : pour signer de l’Ed25519 sans fuite, air-keysign bat le keyring ; le keyring sera pertinent le jour où Air voudra du scellé TPM au repos ou nourrir un consommateur noyau — deux chantiers optionnels et matériel-dépendants, à instruire alors, pas maintenant.


Références : ADR-108 (air-keystore/air-keysign, §5 oracle-safe), ADR-004 (Linux tier-1), Principe 5 (mesurer avant d’optimiser), doctrine crypto pur-Rust, crates/air-sys-syscall/UNSUPPORTED.md, docs/specs/layer-0/family-security.md, docs/specs/config-specification-proposal.md (TPM/keyring pour le chiffrement de config).