Funzionalità

Questa pagina contiene informazioni sulle funzionalità crittografiche di Keystore in Android 6.0 e versioni successive.

Primitive crittografiche

Keystore fornisce le seguenti categorie di operazioni:

  • Generazione di chiavi
  • Importazione ed esportazione di chiavi asimmetriche (nessun avvolgimento delle chiavi)
  • Importazione di chiavi simmetriche grezze (nessun avvolgimento delle chiavi)
  • Crittografia e decrittografia asimmetrica con modalità di riempimento appropriate
  • Firma e verifica asimmetriche con modalità di digestione e imbottitura appropriate
  • Crittografia e decrittografia simmetrica nelle modalità appropriate, inclusa una modalità AEAD
  • Generazione e verifica dei codici di autenticazione dei messaggi simmetrici

Gli elementi del protocollo, come lo scopo, la modalità e il riempimento, nonché i vincoli di controllo dell'accesso , vengono specificati quando le chiavi vengono generate o importate e sono permanentemente vincolate alla chiave, assicurando che la chiave non possa essere utilizzata in nessun altro modo.

Oltre all'elenco sopra, c'è un altro servizio fornito dalle implementazioni di Keymaster, ma che non è esposto come API: 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à.

Primitivi necessari

Tutte le implementazioni di Keymaster forniscono:

  • RSA
    • Supporto per chiavi a 2048, 3072 e 4096 bit
    • Supporto per 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à Digest per la firma RSA:
      • SHA-256
    • Modalità di riempimento per la crittografia/decrittografia RSA:
      • Non imbottito
      • RSAES-OAEP ( PaddingMode::RSA_OAEP )
      • RSAES-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_ENCRYPT )
  • ECDSA
    • Supporto per chiavi a 224, 256, 384 e 521 bit, utilizzando rispettivamente le curve NIST P-224, P-256, P-384 e P-521
    • Modalità Digest per ECDSA:
      • Nessun digest (obsoleto, verrà rimosso in futuro)
      • SHA-256
  • AES
    • Sono supportate chiavi a 128 e 256 bit
    • CBC , CTR, BCE e GCM. L'implementazione GCM non consente l'uso di tag inferiori a 96 bit o lunghezze nonce diverse da 96 bit.
    • Modalità di riempimento PaddingMode::NONE e PaddingMode::PKCS7 è supportato per le modalità CBC ed ECB. Senza riempimento, 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 fortemente consigliati per le implementazioni di Keymaster. Keystore li fornisce nel software se l'implementazione hardware di Keymaster non li fornisce.

Alcune primitive sono consigliate anche per l'interoperabilità con altri sistemi:

  • Dimensioni chiave più piccole per RSA
  • Esponenti pubblici arbitrari per RSA

Controllo accessi chiavi

Le chiavi basate su hardware che non possono mai essere estratte dal dispositivo non forniscono molta sicurezza se un utente malintenzionato può usarle a piacimento (sebbene siano più sicure delle chiavi che possono essere esfiltrate). Pertanto, è fondamentale che Keystore applichi i controlli di accesso.

I controlli di accesso sono definiti come una "lista di autorizzazioni" di coppie di tag/valore. I tag di autorizzazione sono numeri interi a 32 bit ei valori sono di vari tipi. Alcuni tag possono essere ripetuti per specificare più valori. Se un tag può essere ripetuto è specificato nella documentazione del tag . Quando viene creata una chiave, il chiamante specifica un elenco di autorizzazioni. L'implementazione Keymaster alla base di Keystore modifica l'elenco per specificare alcune informazioni aggiuntive, ad esempio se la chiave dispone di una protezione dal rollback, e restituisce un elenco di autorizzazioni "finale", codificato nel BLOB di chiavi restituito. Qualsiasi tentativo di utilizzare la chiave per qualsiasi operazione crittografica fallisce se l'elenco di autorizzazioni finale viene modificato.

Per Keymaster 2 e precedenti, l'insieme di possibili tag è definito nell'enumerazione keymaster_authorization_tag_t ed è fisso in modo permanente (sebbene possa essere esteso). I nomi erano preceduti da 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 nelle enumerazioni. Ad esempio, i possibili valori di TAG::PURPOSE sono definiti in enum keymaster_purpose_t .

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

UINT : numeri interi senza segno a 32 bit. Esempio: TAG::KEY_SIZE

UINT_REP : Uguale a UINT , tranne per il fatto che il tag può essere ripetuto in un elenco di autorizzazioni. La ripetizione indica più valori autorizzati.

ULONG : numeri interi senza segno a 64 bit. Esempio: TAG::RSA_PUBLIC_EXPONENT

ULONG_REP : Come ULONG , tranne per il fatto che il tag può essere ripetuto in un elenco di autorizzazioni. La ripetizione indica più valori autorizzati.

DATE : valori di data/ora, espressi in millisecondi dal 1 gennaio 1970. Esempio: TAG::PRIVKEY_EXPIRE_DATETIME

BOOL : Vero o falso. Una variabile di tipo BOOL è considerata "false" se la variabile non è presente e "true" se presente. Esempio: TAG::ROLLBACK_RESISTANT

BIGNUM : numeri interi di lunghezza arbitraria, espressi come matrice di byte in ordine big-endian. Esempio: TAG::RSA_PUBLIC_EXPONENT

BYTES : una sequenza di byte. Esempio: TAG::ROOT_OF_TRUST

Applicazione hardware e software

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

Tutte le implementazioni:

  • Applica la corrispondenza esatta (non l'applicazione) di tutte le autorizzazioni. Gli elenchi di autorizzazioni nei BLOB di chiavi corrispondono esattamente alle autorizzazioni restituite durante la generazione delle chiavi, compreso l'ordine. Qualsiasi mancata corrispondenza provoca un errore diagnostico.
  • Dichiarare le autorizzazioni i cui valori semantici sono applicati.

Il meccanismo API per dichiarare le autorizzazioni applicate dall'hardware si trova nella struttura keymaster_key_characteristics_t . Divide l'elenco delle autorizzazioni in due sotto-elenchi, hw_enforced e sw_enforced . L'hardware sicuro è responsabile di inserire i valori appropriati in ciascuno, in base a ciò che può imporre.

Inoltre, Keystore implementa l'applicazione basata su software di tutte le autorizzazioni, indipendentemente dal fatto che vengano applicate dall'hardware sicuro o meno.

Ad esempio, considera un'implementazione basata su TrustZone che non supporta la scadenza delle chiavi. È ancora possibile creare una chiave con una data di scadenza. L'elenco delle autorizzazioni di quella chiave includerà il tag TAG::ORIGINATION_EXPIRE_DATETIME con la data di scadenza. Una richiesta a Keystore per le caratteristiche chiave troverà questo tag nell'elenco sw_enforced e l'hardware sicuro non imporrà il requisito di scadenza. Tuttavia, i tentativi di utilizzare la chiave dopo la scadenza verranno rifiutati da Keystore.

Se il dispositivo viene quindi aggiornato con hardware sicuro che supporta la scadenza, una richiesta per le caratteristiche della chiave troverà TAG::ORIGINATION_EXPIRE_DATETIME nell'elenco hw_enforced e i tentativi di utilizzare la chiave dopo la scadenza avranno esito negativo anche se il keystore viene in qualche modo sovvertito o bypassato .

Per ulteriori informazioni su come determinare se le chiavi sono supportate dall'hardware, vedere Attestazione chiave .

Autorizzazioni alla costruzione di messaggi crittografici

I seguenti tag vengono utilizzati per definire le caratteristiche crittografiche delle operazioni utilizzando la chiave associata: TAG::ALGORITHM , TAG::KEY_SIZE , TAG::BLOCK_MODE , TAG::PADDING ::PADDING , TAG::CALLER_NONCE e TAG::DIGEST

TAG::PADDING , TAG::DIGEST e PaddingMode::BLOCK_MODE sono ripetibili, il che significa che più valori possono essere associati a una singola chiave e il valore da utilizzare viene specificato al momento dell'operazione.

Scopo

Alle chiavi è associato un insieme di finalità, espresso come una o più voci di autorizzazione con tag TAG::PURPOSE , che definisce come possono essere utilizzate. Gli scopi sono:

  • KeyPurpose::ENCRYPT
  • KeyPurpose::DECRYPT
  • KeyPurpose::SIGN
  • KeyPurpose::VERIFY

Qualsiasi chiave può avere qualsiasi sottoinsieme di questi scopi. Si noti che alcune combinazioni creano problemi di sicurezza. Ad esempio, una chiave RSA che può essere utilizzata sia per crittografare che per firmare consente a un utente malintenzionato in grado di convincere il sistema a decrittografare dati arbitrari per generare firme.

Importazione e esportazione

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

  • Coppie di chiavi pubbliche e private in formato PKCS#8 con codifica DER, senza crittografia basata su password
  • Chiavi simmetriche come byte grezzi

Per garantire che le chiavi importate possano essere distinte dalle chiavi generate in modo sicuro, TAG::ORIGIN è incluso nell'elenco di autorizzazioni delle chiavi appropriato. Ad esempio, se una chiave è stata generata in hardware sicuro, TAG::ORIGIN con valore KeyOrigin::GENERATED si troverà nell'elenco hw_enforced delle caratteristiche della chiave, mentre una chiave che è stata importata in hardware sicuro avrà il valore KeyOrigin::IMPORTED .

Autenticazione utente

Le implementazioni di Secure Keymaster non implementano l'autenticazione dell'utente, ma dipendono da altre app affidabili che lo fanno. Per l'interfaccia implementata da queste app, vedere la pagina Gatekeeper .

I requisiti di autenticazione dell'utente sono specificati tramite due set di tag. Il primo set indica quale utente può utilizzare la chiave:

  • TAG::ALL_USERS indica che la chiave è utilizzabile da tutti gli utenti. Se presenti, TAG::USER_ID e TAG::USER_SECURE_ID non sono presenti.
  • TAG::USER_ID ha un valore numerico che specifica l'ID dell'utente autorizzato. Tieni presente che questo è l'ID utente Android (per multiutente), non l'UID dell'applicazione, ed è imposto solo da software non sicuro. Se presente, TAG::ALL_USERS non è presente.
  • 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'uso della chiave. Se ripetuta, la chiave può essere utilizzata se uno qualsiasi dei valori è fornito in un token di autenticazione sicuro.

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

  • NO_AUTHENTICATION_REQUIRED indica che non è richiesta l'autenticazione dell'utente, sebbene la chiave possa ancora essere utilizzata solo dalle app in esecuzione come gli utenti specificati da TAG::USER_ID .
  • TAG::AUTH_TIMEOUT è un valore numerico che specifica, in secondi, quanto deve essere aggiornata l'autenticazione dell'utente per autorizzare l'utilizzo della chiave. Ciò si applica solo alle operazioni con chiave privata/segreta. Le operazioni con chiave pubblica non richiedono l'autenticazione. I timeout non incrociano i riavvii; dopo un riavvio, tutte le chiavi sono "mai autenticate". Il timeout può essere impostato su un valore elevato per indicare che l'autenticazione è richiesta una volta per avvio (2^32 secondi sono circa 136 anni; presumibilmente i dispositivi Android vengono riavviati più spesso).

Associazione del cliente

L'associazione del client, l'associazione di una chiave con una particolare applicazione client, viene eseguita tramite un ID client opzionale e alcuni dati client opzionali ( TAG::APPLICATION_ID e TAG::APPLICATION_DATA , rispettivamente). Keystore tratta questi valori come BLOB opachi, assicurando solo che gli stessi BLOB presentati durante la generazione/importazione della chiave vengano presentati per ogni utilizzo e siano identici byte per byte. I dati di associazione del client non vengono restituiti da Keymaster. Il chiamante deve conoscerlo per poter utilizzare la chiave.

Questa funzione non è esposta alle applicazioni.

Scadenza

Keystore supporta la limitazione dell'utilizzo delle chiavi in ​​base alla data. L'inizio della validità della chiave e le scadenze 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 viene 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 "creare" un nuovo testo cifrato/firma/ecc., o per "utilizzare" un testo cifrato/firma/ecc. Si noti che questa distinzione non è esposta alle applicazioni.

I 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 decrittografare/verificare i messaggi.

Poiché l'ora dell'orologio da parete è fornita dal mondo non protetto, è improbabile che i tag relativi alla scadenza siano nell'elenco applicato dall'hardware. L'applicazione della scadenza dell'hardware richiederebbe che il mondo sicuro ottenga in qualche modo tempo e dati affidabili, ad esempio tramite un protocollo di risposta alle sfide con un server orario remoto affidabile.

Root of trust binding

Keystore richiede che le chiavi siano associate a una radice di fiducia, che è una stringa di bit fornita all'hardware protetto di Keymaster durante l'avvio, preferibilmente dal bootloader. Questa stringa di bit è crittograficamente vincolata a ogni chiave gestita da Keymaster.

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

Chiavi autonome

Alcuni hardware sicuri Keymaster possono scegliere di archiviare il materiale della chiave internamente e restituire gli handle anziché il materiale della chiave crittografata. Oppure potrebbero esserci altri casi in cui le chiavi non possono essere utilizzate fino a quando non è disponibile un altro componente di sistema non sicuro o protetto. Il Keymaster HAL 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 Keymaster in esecuzione. I tag associati a una chiave possono essere ispezionati per vedere se una chiave è autonoma. Attualmente sono definiti solo due valori:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

Questa funzione non è esposta alle applicazioni.

Velocità

Quando viene creato, la velocità di utilizzo massima può essere specificata con TAG::MIN_SECONDS_BETWEEN_OPS . Le implementazioni di TrustZone 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 sarà probabilmente di dimensioni limitate, ma può contenere almeno 16 voci. Nel caso in cui la tabella sia piena e nessuna voce possa essere aggiornata o eliminata, proteggere le implementazioni hardware "fail safe", preferendo rifiutare tutte le operazioni con chiave a velocità limitata fino alla scadenza di una delle voci. È accettabile che tutte le voci scadano al riavvio.

Le chiavi possono anche essere limitate a n usi per avvio con TAG::MAX_USES_PER_BOOT . Ciò richiede anche una tabella di tracciamento, che possa ospitare almeno quattro chiavi e che sia anche sicura. Tieni presente che le applicazioni non saranno in grado di creare chiavi limitate per avvio. Questa funzione non è esposta tramite Keystore ed è riservata alle operazioni di sistema.

Questa funzione non è esposta alle applicazioni.

Re-seeding del generatore di numeri casuali

Poiché l'hardware sicuro genera numeri casuali per il materiale della chiave e i vettori di inizializzazione (IV) e poiché i generatori di numeri casuali hardware potrebbero non essere sempre completamente affidabili, Keymaster HAL fornisce un'interfaccia per consentire al client di fornire ulteriore entropia che sarà mescolata al casuale numeri generati.

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

Questa funzionalità non è esposta alle applicazioni ma è utilizzata dal framework, che fornisce regolarmente ulteriore entropia, recuperata da un'istanza Java SecureRandom, all'hardware protetto.