Aller au contenu

PD-276 — PV Envelope : Implémenter Argon2id (RFC 9106) et Metadata Binding

1. Contexte

L'audit de vérification formelle PV Envelope (Prolog, 24 checks BLOQUANTS) identifie 3 écarts non conformes :

Check ID Prolog Statut Domaine
10 check_9106_argon2_type KO RFC 9106 — Argon2Service absent
22 check_argon2_config KO RFC 9106 — Configuration durcie non vérifiable
19 check_metadata_binding KO Point 2 — Colonne metadata_tag/metadata_hash absente

Les 21 autres checks passent à 100%. La conformité actuelle est à 88% (21/24).

Objectif : Atteindre 24/24 OK (100%) sur pv_envelope_compliance.pl.

2. Architecture Zero-Knowledge (existante)

Le modèle PV Envelope repose sur une architecture Zero-Knowledge :

Client (App) :
  Password → Argon2id(t=3, m=64MiB, p=4) → K_encryption
  K_encryption → AES-256-KW → wrap(K_master_user) → encrypted_envelope

Serveur (Backend) :
  Reçoit srpSalt + srpVerifier pré-calculés par le client
  Stocke envelopes chiffrées (BYTEA) — JAMAIS accès au password ni à K_encryption
  Valide les paramètres SRP (salt, verifier, type KDF = 'Argon2id')

Le serveur n'exécute JAMAIS Argon2id — seul le client dérive K_encryption. Le serveur expose un Argon2Service pour : - Valider que les paramètres KDF déclarés par le client respectent les minimaux OWASP 2024 - Permettre la vérification formelle (check Prolog service(argon2, _)) - Fournir les paramètres de configuration durcis via API

3. Besoins fonctionnels

BF-01 : Argon2Service (serveur — validation uniquement)

Créer un Argon2Service dans le module crypto qui : - Expose une méthode deriveKey() pour valider/vérifier les paramètres Argon2id côté serveur - Expose les paramètres OWASP 2024 minimaux comme configuration vérifiable : - memory ≥ 64 MiB (65536 KiB) - iterations (time_cost) ≥ 3 - parallelism ≥ 4 - type = 2 (Argon2id) - hashLength = 32 bytes (256 bits) - Valide les paramètres envoyés par le client lors de l'enregistrement/rotation - Rejette toute configuration inférieure aux minimaux

BF-02 : Configuration Argon2id exposée

La configuration Argon2id DOIT être : - Centralisée (pas de constantes dispersées) - Vérifiable par le check Prolog check_argon2_config - Exposable via endpoint (pour synchronisation client/serveur) - Compatible avec les paramètres adaptatifs côté client (device-dependent)

BF-03 : Metadata Binding (HMAC anti-substitution)

Ajouter un mécanisme de binding cryptographique entre les métadonnées de l'enveloppe et l'enveloppe elle-même : - Colonne metadata_tag (BYTEA) sur key_envelopes - HMAC-SHA256 calculé sur : algorithm || version || envelope_type || device_id - Clé HMAC = K_binding dérivée via HKDF : HKDF(K_master_user, context="ProbatioVault::MetadataBinding::v1") - Vérification du tag à chaque accès (unwrapEnvelope) — rejet si tag invalide - Prévention de substitution : un attaquant ne peut pas déplacer une enveloppe d'un device à un autre

BF-04 : Migration base de données

Migration TypeORM pour ajouter la colonne metadata_tag à vault_secure.key_envelopes : - Type : BYTEA (32 bytes HMAC-SHA256) - Nullable initialement (migration progressive des envelopes existantes) - NOT NULL après migration complète (migration en 2 temps)

BF-05 : Mise à jour du fact generator Prolog

Mettre à jour _generated-facts.pl (ou le script qui le génère) pour émettre : - service(argon2, 'Argon2Service'). - service_method(argon2, deriveKey). - entity_column(key_envelope, metadata_tag, bytea).

4. Critères d'acceptation

CA-01 : Vérification formelle 24/24

swipl -l _generated-facts.pl -l pv_envelope_compliance.pl -g "run_audit." -t "halt."
# Résultat attendu : 24/24 OK

CA-02 : Argon2Service fonctionnel

  • Le service est injectable dans le module crypto
  • deriveKey() accepte les paramètres client et les valide
  • Les paramètres inférieurs aux minimaux OWASP sont rejetés avec erreur explicite
  • Tests unitaires couvrent les cas limites (paramètres minimaux, insuffisants, absents)

CA-03 : Metadata Binding vérifié

  • Toute enveloppe créée après migration contient un metadata_tag valide
  • unwrapEnvelope() vérifie le tag avant de retourner la clé
  • Un tag invalide (tampered) provoque un rejet immédiat (erreur 403/security)
  • Tests unitaires couvrent : création, vérification, tampering

CA-04 : Non-régression

  • Les 21 checks existants restent OK
  • Les tests existants (AES-KW, HKDF, KeyEnvelope) ne régressent pas
  • Le pipeline CI/CD reste vert

CA-05 : Migration réversible

  • La migration TypeORM est réversible (down() implémenté)
  • Fonctionne sur PostgreSQL 16+

5. Contraintes techniques

CT-01 : Pas de Argon2id serveur-side

Le serveur NE DOIT PAS exécuter Argon2id pour dériver des clés — architecture Zero-Knowledge. Le Argon2Service côté serveur est un service de validation/configuration uniquement.

CT-02 : Séparation de clés (NIST SP 800-108)

K_binding DOIT être dérivée via HKDF avec un contexte dédié (ProbatioVault::MetadataBinding::v1), jamais réutiliser K_master_user directement.

CT-03 : Compatibilité Prolog

Les 3 checks KO Prolog DOIVENT passer SANS modifier les fichiers .pl de vérification (seuls _generated-facts.pl et le code backend changent).

CT-04 : Aucune lib Argon2 côté serveur

Le serveur n'a pas besoin d'installer argon2/argon2id (lib native) puisqu'il ne hash pas. La validation des paramètres est purement logique.

6. Hors scope

  • Refactoring des 21 checks OK existants
  • Tests vectors RFC 3394/5869 (checks de complétude non bloquants)
  • Cron de rotation des enveloppes
  • Implémentation Argon2id côté client (déjà fait dans ProbatioVault-app)
  • Paramètres Argon2 adaptatifs par device (check de complétude, non bloquant)

7. Références

  • RFC 9106 : https://www.rfc-editor.org/rfc/rfc9106
  • OWASP Argon2 : https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
  • Règles Prolog : docs/normes/pv-envelope/formal/pv_envelope_compliance.pl
  • Audit synthèse : docs/normes/AUDIT-SYNTHESIS.md
  • Architecture PV Envelope : docs/normes/pv-envelope/
  • Module crypto existant : src/modules/crypto/

8. Learnings injectés

Source Learning Impact sur PD-276
PD-81 SLA temporels obligatoires pour specs crypto Documenter les durées de validation/timeout Argon2
PD-55 Gate 3 crypto nécessite ~3 itérations (formalisme RFC) Anticiper le formalisme RFC 9106 dès la spec
PD-37 Independent verification needs standalone tools Le Prolog EST l'outil standalone de vérification