Funzionalità

Questa pagina contiene informazioni sulle funzionalità di crittografia di Android Keystore, fornite dall'implementazione sottostante di KeyMint (o Keymaster).

Primitive di crittografia

Keystore fornisce le seguenti categorie di operazioni:

  • Creazione di chiavi, con conseguente materiale della chiave privata o segreta accessibile solo all'ambiente sicuro. I client possono creare chiavi nei seguenti modi:
    • Generazione di chiavi nuove
    • Importazione di materiale chiave non criptato
    • Importazione del materiale chiave criptato
  • Attestazione della chiave: la creazione di una chiave asimmetrica genera un certificato contenente la parte della chiave pubblica della coppia di chiavi. Questo certificato contiene anche, facoltativamente, informazioni sui metadati per la chiave e lo stato del dispositivo, tutte firmate da una chiave che rimanda a una radice attendibile.
  • Operazioni crittografiche:
    • Crittografia e decrittografia simmetrica (AES, 3DES)
    • Decriptazione asimmetrica (RSA)
    • Firma asimmetrica (ECDSA, RSA)
    • Firma e verifica simmetriche (HMAC)
    • Accordo su chiavi asimmetriche (ECDH)

Tieni presente che Keystore e KeyMint non gestiscono le operazioni con le chiavi pubbliche per le chiavi asimmetriche.

Gli elementi del protocollo, come scopo, modalità e padding, nonché i vincoli di controllo dell'accesso, vengono specificati quando le chiavi vengono generate o importate e sono associati in modo permanente alla chiave, garantendo che non possa essere utilizzata in altri modi.

Oltre all'elenco riportato sopra, le implementazioni di KeyMint (in precedenza Keymaster) forniscono un altro servizio, che non è esposto come API: la generazione di numeri casuali. Viene utilizzato internamente per la generazione di chiavi, vettori di inizializzazione (IV), riempimento casuale e altri elementi di protocolli sicuri che richiedono casualità.

Primitive necessarie

Tutte le implementazioni di KeyMint forniscono:

  • RSA
    • Supporto di chiavi a 2048, 3072 e 4096 bit
    • Supporto dell'esponente pubblico F4 (2^16+1)
    • Modalità di riempimento per la firma RSA:
      • RSASSA-PSS (PaddingMode::RSA_PSS)
      • RSASSA-PKCS1-v1_5 (PaddingMode::RSA_PKCS1_1_5_SIGN)
    • Modalità di riepilogo per la firma RSA:
      • SHA-256
    • Modalità di padding per la crittografia/decrittografia RSA:
      • Senza imbottitura
      • RSAES-OAEP (PaddingMode::RSA_OAEP)
      • RSAES-PKCS1-v1_5 (PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
  • ECDSA
    • Sono supportate chiavi a 224, 256, 384 e 521 bit, utilizzando rispettivamente le curve NIST P-224, P-256, P-384 e P-521.
    • Modalità di riepilogo per ECDSA:
      • Nessun riepilogo (deprecato, verrà rimosso in futuro)
      • SHA-256
  • AES
    • Sono supportate chiavi a 128 e 256 bit
    • CBC, CTR, ECB e GCM. L'implementazione di GCM non consente l'utilizzo di tag più piccoli di 96 bit o lunghezze nonce diverse da 96 bit.
    • Le modalità di padding PaddingMode::NONE e PaddingMode::PKCS7 sono supportate per le modalità CBC ed ECB. Senza padding, la crittografia in modalità CBC o ECB non riesce se l'input non è un multiplo della dimensione del blocco.
  • HMAC SHA-256, con qualsiasi dimensione della chiave fino ad almeno 32 byte.

SHA1 e gli altri membri della famiglia SHA2 (SHA-224, SHA384 e SHA512) sono vivamente consigliati per le implementazioni di KeyMint. Keystore le fornisce nel software se l'implementazione hardware di KeyMint non le fornisce.

Alcuni primitivi sono consigliati anche per l'interoperabilità con altri sistemi:

  • Dimensioni delle chiavi più piccole per RSA
  • Esponenti pubblici arbitrari per RSA

Controllo dell'accesso alle chiavi

Le chiavi basate su hardware che non possono mai essere estratte dal dispositivo non forniscono molta sicurezza se un malintenzionato può utilizzarle a suo piacimento (anche se sono più sicure delle chiavi che possono essere esfiltrate). Pertanto, è fondamentale che Keystore applichi i controlli dell'accesso.

I controlli dell'accesso sono definiti come un "elenco di autorizzazione" di coppie tag/valore. I tag di autorizzazione sono numeri interi a 32 bit e i valori sono di vari tipi. Alcuni tag possono essere ripetuti per specificare più valori. La possibilità di ripetere un tag è specificata nell'interfaccia HAL KeyMint. Quando viene creata una chiave, il chiamante specifica un elenco di autorizzazioni. L'implementazione di KeyMint alla base di Keystore modifica l'elenco per specificare alcune informazioni aggiuntive, ad esempio se la chiave ha la protezione dal rollback, e restituisce un elenco di autorizzazioni "finale", codificato nel blob della chiave restituito. Qualsiasi tentativo di utilizzare la chiave per qualsiasi operazione crittografica non va a buon fine se l'elenco delle autorizzazioni finale viene modificato.

Per Keymaster 2 e versioni precedenti, l'insieme di tag possibili è definito nell'enumerazione keymaster_authorization_tag_t ed è fissato in modo permanente (anche se può essere esteso). I nomi avevano il prefisso KM_TAG. I primi quattro bit degli ID tag vengono utilizzati per indicare il tipo.

Keymaster 3 ha modificato il prefisso KM_TAG in Tag::.

I tipi possibili includono:

ENUM: i valori di molti tag sono definiti in enumerazioni. Ad esempio, i valori possibili di TAG::PURPOSE sono definiti nell'enum keymaster_purpose_t.

ENUM_REP: come ENUM, tranne che il tag può essere ripetuto in un elenco di autorizzazioni. La ripetizione indica più valori autorizzati. Ad esempio, una chiave di crittografia probabilmente ha KeyPurpose::ENCRYPT e KeyPurpose::DECRYPT.

Quando KeyMint crea una chiave, il chiamante specifica un elenco di autorizzazioni per la chiave. Questo elenco viene modificato da Keystore e KeyMint per aggiungere ulteriori vincoli e l'implementazione KeyMint sottostante codifica l'elenco di autorizzazioni finale nel keyblob restituito. L'elenco di autorizzazioni codificato è associato crittograficamente al keyblob, in modo che qualsiasi tentativo di modificare l'elenco di autorizzazioni (incluso l'ordine) generi un keyblob non valido che non può essere utilizzato per operazioni crittografiche.

Applicazione hardware e software

Non tutte le implementazioni hardware sicure contengono le stesse funzionalità. Per supportare una serie di approcci, Keymaster distingue tra l'applicazione del controllo dell'accesso al mondo sicuro e non sicuro, ovvero l'applicazione hardware e software, rispettivamente.

Questo valore è esposto nell'API KeyMint con il campo securityLevel del tipo KeyCharacteristics. L'hardware sicuro è responsabile dell'inserimento delle autorizzazioni nel KeyCharacteristics con il livello di sicurezza appropriato, in base a ciò che può applicare. Queste informazioni vengono visualizzate anche nei record di attestazione per le chiavi asimmetriche: le caratteristiche della chiave per SecurityLevel::TRUSTED_ENVIRONMENT o SecurityLevel::STRONGBOX vengono visualizzate nell'elenco hardwareEnforced, mentre le caratteristiche per SecurityLevel::SOFTWARE o SecurityLevel::KEYSTORE vengono visualizzate nell'elenco softwareEnforced.

Ad esempio, i vincoli sull'intervallo di data e ora in cui è possibile utilizzare una chiave in genere non vengono applicati dall'ambiente sicuro, perché non ha accesso affidabile alle informazioni su data e ora. Di conseguenza, le autorizzazioni come Tag::ORIGINATION_EXPIRE_DATETIME vengono applicate da Keystore in Android e avrebbero SecurityLevel::KEYSTORE.

Per saperne di più su come determinare se le chiavi e le relative autorizzazioni sono supportate dall'hardware, vedi Attestazione delle chiavi.

Autorizzazioni di creazione di messaggi crittografici

I seguenti tag vengono utilizzati per definire le caratteristiche crittografiche delle operazioni che utilizzano la chiave associata:

  • Tag::ALGORITHM
  • Tag::KEY_SIZE
  • Tag::BLOCK_MODE
  • Tag::PADDING
  • Tag::CALLER_NONCE
  • Tag::DIGEST
  • Tag::MGF_DIGEST

I seguenti tag sono ripetibili, il che significa che più valori possono essere associati a una singola chiave:

  • Tag::BLOCK_MODE
  • Tag::PADDING
  • Tag::DIGEST
  • Tag::MGF_DIGEST

Il valore da utilizzare viene specificato al momento dell'operazione.

Finalità

Le chiavi hanno un insieme di scopi associati, espressi come una o più voci di autorizzazione con il tag Tag::PURPOSE, che definisce come possono essere utilizzate. Gli scopi sono definiti in KeyPurpose.aidl.

Tieni presente che alcune combinazioni di valori di scopo creano problemi di sicurezza. Ad esempio, una chiave RSA che può essere utilizzata sia per criptare che per firmare consente a un malintenzionato che può convincere il sistema a decriptare dati arbitrari di generare firme.

Importazione di una chiave

Keymaster supporta solo l'esportazione di chiavi pubbliche in formato X.509 e l'importazione di:

  • Coppie di chiavi asimmetriche in formato PKCS#8 con codifica DER (senza crittografia basata su password)
  • Chiavi simmetriche come byte non elaborati

Per garantire che le chiavi importate possano essere distinte da quelle generate in modo sicuro, Tag::ORIGIN è incluso nell'elenco di autorizzazione delle chiavi appropriato. Ad esempio, se una chiave è stata generata in un hardware sicuro, Tag::ORIGIN con valore KeyOrigin::GENERATED si trova nell'elenco hw_enforced delle caratteristiche della chiave, mentre una chiave importata in un hardware sicuro ha il valore KeyOrigin::IMPORTED.

Autenticazione utente

Le implementazioni sicure di KeyMint non implementano l'autenticazione utente, ma dipendono da altre app attendibili che lo fanno. Per l'interfaccia implementata da queste app, consulta la pagina Gatekeeper.

I requisiti di autenticazione dell'utente vengono specificati tramite due set di tag. Il primo insieme indica quali metodi di autenticazione consentono l'utilizzo della chiave:

  • Tag::USER_SECURE_ID ha un valore numerico a 64 bit che specifica l'ID utente sicuro fornito in un token di autenticazione sicuro per sbloccare l'utilizzo della chiave. Se ripetuta, la chiave può essere utilizzata se uno dei valori viene fornito in un token di autenticazione sicuro.

Il secondo insieme indica se e quando l'utente deve essere autenticato. Se nessuno di questi tag è presente, ma Tag::USER_SECURE_ID è presente, l'autenticazione è richiesta per ogni utilizzo della chiave.

  • Tag::NO_AUTHENTICATION_REQUIRED indica che non è richiesta l'autenticazione utente, anche se l'accesso alla chiave è comunque limitato all'app proprietaria (e a qualsiasi app a cui concede l'accesso).
  • Tag::AUTH_TIMEOUT è un valore numerico che specifica, in secondi, quanto recente deve essere l'autenticazione utente per autorizzare l'utilizzo della chiave. I timeout non vengono mantenuti dopo i riavvii; dopo un riavvio, tutte le autenticazioni vengono invalidate. Il timeout può essere impostato su un valore elevato per indicare che l'autenticazione è richiesta una volta per avvio (2^32 secondi corrispondono a circa 136 anni; presumibilmente i dispositivi Android vengono riavviati più spesso).

Richiedere un dispositivo sbloccato

Le chiavi con Tag::UNLOCKED_DEVICE_REQUIRED sono utilizzabili solo quando il dispositivo è sbloccato. Per la semantica dettagliata, consulta KeyProtection.Builder#setUnlockedDeviceRequired(boolean).

UNLOCKED_DEVICE_REQUIRED è applicato da Keystore, non da KeyMint. Tuttavia, in Android 12 e versioni successive, Keystore protegge crittograficamente le chiavi UNLOCKED_DEVICE_REQUIRED mentre il dispositivo è bloccato per garantire che, nella maggior parte dei casi, non possano essere utilizzate anche se Keystore è compromesso mentre il dispositivo è bloccato.

A questo scopo, Keystore "supercrittografa" tutte le chiavi UNLOCKED_DEVICE_REQUIRED prima di archiviarle nel suo database e, quando possibile, protegge le chiavi di supercrittografia (superchiavi) mentre il dispositivo è bloccato in modo che possano essere recuperate solo sbloccando correttamente il dispositivo. Il termine "supercrittografia" viene utilizzato perché questo livello di crittografia viene applicato in aggiunta al livello di crittografia che KeyMint applica già a tutte le chiavi.

Ogni utente (inclusi i profili) ha due superchiavi associate a UNLOCKED_DEVICE_REQUIRED:

  • La super chiave simmetrica UnlockedDeviceRequired. Questa è una chiave AES‑256‑GCM. Cripta le chiavi UNLOCKED_DEVICE_REQUIRED importate o generate mentre il dispositivo è sbloccato per l'utente.
  • La super chiave asimmetrica UnlockedDeviceRequired. Si tratta di una coppia di chiavi ECDH P-521. Cripta le chiavi UNLOCKED_DEVICE_REQUIRED importate o generate mentre il dispositivo è bloccato per l'utente. Le chiavi criptate con questa chiave asimmetrica vengono ricriptate con la chiave simmetrica al primo utilizzo (che può avvenire solo quando il dispositivo è sbloccato).

Keystore genera queste super chiavi al momento della creazione dell'utente e le memorizza nel suo database, criptate dalla password sintetica dell'utente. In questo modo possono essere recuperati utilizzando il PIN, la sequenza o la password equivalenti.

Keystore memorizza nella cache anche queste superchiavi in memoria, consentendogli di operare sulle chiavi UNLOCKED_DEVICE_REQUIRED. Tuttavia, tenta di memorizzare nella cache le parti segrete di queste chiavi solo mentre il dispositivo è sbloccato per l'utente. Quando il dispositivo è bloccato per l'utente, Keystore azzera la copia memorizzata nella cache delle parti segrete di queste super chiavi, se possibile. Nello specifico, quando il dispositivo è bloccato per l'utente, Keystore seleziona e applica uno dei tre livelli di protezione per le superchiavi UnlockedDeviceRequired dell'utente:

  • Se l'utente ha attivato solo il PIN, la sequenza o la password, Keystore azera le parti segrete delle superchiavi memorizzate nella cache. In questo modo, le super chiavi sono recuperabili solo tramite la copia criptata nel database che può essere decriptata solo tramite PIN, sequenza o password equivalenti.
  • Se l'utente ha attivato solo la biometria di classe 3 ("forte") e il PIN, la sequenza o la password, Keystore fa in modo che le super chiavi siano recuperabili tramite una qualsiasi delle biometrie di classe 3 registrate dall'utente (in genere l'impronta), come alternativa al PIN, alla sequenza o alla password equivalenti. A questo scopo, genera una nuova chiave AES-256-GCM, cripta le parti segrete delle superchiavi, importa la chiave AES-256-GCM in KeyMint come chiave associata ai dati biometrici che richiede l'autenticazione biometrica per essere riuscita negli ultimi 15 secondi e azzera le copie in testo non crittografato di tutte queste chiavi.
  • Se l'utente ha una biometria di classe 1 ("di convenienza"), una biometria di classe 2 ("debole") o un trust agent di sblocco attivo abilitato, Keystore mantiene le superchiavi memorizzate nella cache in testo normale. In questo caso, la sicurezza crittografica per le chiavi UNLOCKED_DEVICE_REQUIRED non viene fornita. Gli utenti possono evitare questo fallback meno sicuro non attivando questi metodi di sblocco. I metodi di sblocco più comuni che rientrano in queste categorie sono lo sblocco con il volto su molti dispositivi e lo sblocco con uno smartwatch accoppiato.

Quando il dispositivo viene sbloccato per l'utente, Keystore recupera le superchiavi UnlockedDeviceRequired dell'utente, se possibile. Per lo sblocco equivalente tramite PIN, sequenza o password, decripta la copia di queste chiavi memorizzata nel database. In caso contrario, controlla se ha salvato una copia di queste chiavi criptate con una chiave associata alla biometria e, in caso affermativo, tenta di decriptarla. Questa operazione ha esito positivo solo se l'utente ha eseguito l'autenticazione con una biometria di classe 3 negli ultimi 15 secondi, applicata da KeyMint (non Keystore).

Associazione client

Il binding del client, ovvero l'associazione di una chiave a una determinata app client, viene eseguito tramite un ID client facoltativo e alcuni dati client facoltativi (Tag::APPLICATION_ID e Tag::APPLICATION_DATA, rispettivamente). Keystore tratta questi valori come blob opachi, assicurandosi solo che gli stessi blob presentati durante la generazione/l'importazione delle chiavi vengano presentati per ogni utilizzo e siano identici byte per byte. I dati di binding del client non vengono restituiti da KeyMint. Il chiamante deve conoscerlo per utilizzare la chiave.

Questa funzionalità non è esposta alle app.

Scadenza

Keystore supporta la limitazione dell'utilizzo delle chiavi in base alla data. L'inizio della validità e la scadenza della chiave possono essere associati a una chiave e Keymaster si rifiuta di eseguire operazioni sulla chiave se la data/ora corrente non rientra nell'intervallo valido. L'intervallo di validità della chiave è specificato con i tag Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME. La distinzione tra "origine" e "utilizzo" si basa sul fatto che la chiave venga utilizzata per "originare" un nuovo testo cifrato/firma/ecc. o per "utilizzare" un testo cifrato/firma/ecc. esistente. Tieni presente che questa distinzione non è esposta alle app.

I tag Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME sono facoltativi. Se i tag sono assenti, si presume che la chiave in questione possa sempre essere utilizzata per decriptare/verificare i messaggi.

Poiché il tempo reale è fornito dal mondo non sicuro, i tag relativi alla scadenza si trovano nell'elenco applicato dal software.

Associazione della radice di attendibilità

Keystore richiede che le chiavi siano associate a una radice di attendibilità, ovvero una stringa di bit fornita all'hardware sicuro KeyMint durante l'avvio, preferibilmente dal bootloader. Questa stringa di bit è associata crittograficamente a ogni chiave gestita da KeyMint.

La radice di attendibilità è costituita dalla chiave pubblica utilizzata per verificare la firma dell'immagine di avvio e dallo stato di blocco del dispositivo. Se la chiave pubblica viene modificata per consentire l'utilizzo di un'immagine di sistema diversa o se lo stato di blocco viene modificato, nessuna delle chiavi protette da KeyMint create dal sistema precedente è utilizzabile, a meno che non venga ripristinata la precedente radice di attendibilità e venga avviato un sistema firmato con quella chiave. L'obiettivo è aumentare il valore dei controlli di accesso alle chiavi applicati dal software rendendo impossibile a un sistema operativo installato da un malintenzionato utilizzare le chiavi KeyMint.

Chiavi autonome

Alcuni hardware sicuri KeyMint possono scegliere di archiviare internamente il materiale della chiave e restituire gli handle anziché il materiale della chiave criptato. Oppure potrebbero esserci altri casi in cui le chiavi non possono essere utilizzate finché non è disponibile un altro componente di sistema non sicuro o sicuro. L'HAL KeyMint consente al chiamante di richiedere che una chiave sia "autonoma" tramite il tag TAG::STANDALONE, il che significa che non sono necessarie risorse diverse dal blob e dal sistema KeyMint in esecuzione. I tag associati a una chiave possono essere esaminati per verificare se una chiave è autonoma. Al momento sono definiti solo due valori:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

Questa funzionalità non è esposta alle app.

Velocità

Una volta creato, è possibile specificare la velocità di utilizzo massima con TAG::MIN_SECONDS_BETWEEN_OPS. Le implementazioni di TrustZone si rifiutano di eseguire operazioni crittografiche con quella chiave se un'operazione è stata eseguita meno di TAG::MIN_SECONDS_BETWEEN_OPS secondi prima.

L'approccio semplice all'implementazione dei limiti di velocità è una tabella di ID chiave e timestamp dell'ultimo utilizzo. Questa tabella ha dimensioni limitate, ma contiene almeno 16 voci. Nel caso in cui la tabella sia piena e non sia possibile aggiornare o eliminare voci, le implementazioni hardware sicure "fail safe" preferiscono rifiutare tutte le operazioni con chiavi con limite di velocità finché una delle voci non scade. È accettabile che tutte le voci scadano al riavvio.

Le chiavi possono anche essere limitate a n utilizzi per avvio con TAG::MAX_USES_PER_BOOT. Richiede anche una tabella di monitoraggio, che contenga almeno quattro chiavi e che sia a prova di errore. Tieni presente che le app non possono creare chiavi limitate per avvio. Questa funzionalità non è esposta tramite Keystore ed è riservata alle operazioni di sistema.

Questa funzionalità non è esposta alle app.

Riavvio del generatore di numeri casuali

Poiché l'hardware sicuro genera numeri casuali per il materiale delle chiavi e i vettori di inizializzazione (IV) e poiché i generatori di numeri casuali hardware potrebbero non essere sempre completamente affidabili, l'HAL KeyMint fornisce un'interfaccia per consentire al client di fornire ulteriore entropia, che viene combinata con i numeri casuali generati.

Utilizza un generatore di numeri casuali hardware come origine principale del seme. I dati iniziali forniti tramite l'API esterna non possono essere l'unica origine di casualità utilizzata per la generazione dei numeri. Inoltre, l'operazione di mixaggio utilizzata deve garantire che l'output casuale sia imprevedibile se una delle origini di inizializzazione è imprevedibile.