C_DigestKey digests a sensitive EC private key's CKA_VALUE: no check that the object is a secret key

Aperta Adatta ai principianti
#913 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
cpp

Direzione di ricerca

Inizia in src/lib/SoftHSM.cpp, in corrispondenza di SoftHSM::C_DigestKey, e verifica come viene convalidato l’oggetto prima della whitelist SHA-1/SHA-2. Fai in modo che il calcolo del digest delle chiavi segrete continui a funzionare e restituisci CKR_KEY_INDIGESTIBLE per le altre classi di oggetti, come descritto nell’issue. Controlla i test esistenti per digest-key e aggiungi la copertura per una chiave privata EC e una chiave segreta; il lavoro è completato quando il caso della chiave privata viene rifiutato mentre quello della chiave segreta continua ad avere successo.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

C_DigestKey does not check the class of the object it digests. With SHA-1 or SHA-2 it digests the CKA_VALUE of an EC private key, even one with CKA_SENSITIVE = TRUE and CKA_EXTRACTABLE = FALSE, and returns SHA-x of the private scalar. C_GetAttributeValue on the same attribute correctly answers CKR_ATTRIBUTE_SENSITIVE.

Seen on 2.7.0-28-g884cb38. The code is the same on main (9ad8734).

This is not about #189. Digesting a sensitive secret key with SHA-x, as #189/#300 allowed for KDF use, is fine and keeps working. This issue is only about objects that are not secret keys.

Expected (PKCS#11 v3.2)

§5.12.4 C_DigestKey "continues a multiple-part message-digesting operation by digesting the value of a secret key". For any other object, §5.1.6 gives CKR_KEY_INDIGESTIBLE ("perhaps the key isn't a secret key"), or CKR_KEY_HANDLE_INVALID.

Results

These ran logged in as the user, each case in its own process. The private key is P-256, imported with a known scalar d = 01 02 … 20 (32 bytes) and CKA_SENSITIVE = TRUE, CKA_EXTRACTABLE = FALSE, CKA_TOKEN = FALSE:

Call Result
C_DigestInit(CKM_SHA256) + C_DigestKey of a sensitive AES key (control) CKR_OK (correct)
C_GetAttributeValue(CKA_VALUE) of the EC private key CKR_ATTRIBUTE_SENSITIVE (correct)
C_DigestInit(CKM_SHA256) + C_DigestKey of the EC private key + C_DigestFinal CKR_OK, digest ae216c2ef5247a3782c135efa279a3e4cdc61094270f5d2be58c6204b7a612c9

That digest is SHA-256 of the private scalar:

$ printf '%s' 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 | xxd -r -p | openssl dgst -sha256 -r
ae216c2ef5247a3782c135efa279a3e4cdc61094270f5d2be58c6204b7a612c9 *stdin
Cause

SoftHSM::C_DigestKey (src/lib/SoftHSM.cpp) looks up the handle, checks read access, and for SHA-1/SHA-2 skips the CKA_EXTRACTABLE/CKA_SENSITIVE checks (the whitelist from #300). It then digests CKA_VALUE of whatever object it got, and CKA_CLASS is never checked. So any object that stores its secret in CKA_VALUE gets digested: EC, EdDSA, DSA and DH private keys, and also data objects. RSA private keys don't, because they have no CKA_VALUE; for those the call returns CKR_KEY_INDIGESTIBLE.

Suggested fix

Before the whitelist, refuse anything that is not a secret key:

if (key->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_SECRET_KEY)
    return CKR_KEY_INDIGESTIBLE;
Impact

The digest doesn't reveal the scalar. But it is a value computed from a key the token was told never to reveal, and it is a stable fingerprint of that key. An application can also mix its own data in through C_DigestUpdate before C_DigestKey. On a token that keeps private keys sensitive, that exposure isn't expected.

Found while running the KerckhoffsLabs.Security.Cryptography.Pkcs11 conformance suite, which has to skip this case on SoftHSM2.

Lingua principale
C++
Stelle
1.1k
Fork
434
Merge medio
12g 14h
PR unite (30g)
2

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di softhsm/SoftHSMv2

Tutte le issue di softhsm/SoftHSMv2

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.