Caratteristiche

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 key wrapping)
  • Importazione di chiavi simmetriche grezze (nessun avvolgimento delle chiavi)
  • Crittografia e decrittografia asimmetrica con modalità di riempimento appropriate
  • Firma e verifica asimmetrica con digestione e modalità di riempimento appropriate
  • Crittografia e decrittografia simmetrica in modalità appropriate, inclusa una modalità AEAD
  • Generazione e verifica dei codici di autenticazione dei messaggi simmetrici

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

Oltre all'elenco precedente, esiste un altro servizio fornito dalle implementazioni Keymaster, ma 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 Keymaster forniscono:

  • RSA
    • Supporto chiavi 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 crittografia/decrittografia RSA:
      • Non imbottito
      • RSAES-OAEP ( PaddingMode::RSA_OAEP )
      • RSAES-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_ENCRYPT )
  • ECDSA
    • Sono supportati il ​​supporto delle 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 (deprecato, 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 di lunghezze nonce diverse da 96 bit.
    • Modalità di riempimento PaddingMode::NONE e PaddingMode::PKCS7 sono supportati per le modalità CBC ed ECB. Senza riempimento, la crittografia in modalità CBC o ECB fallisce se l'input non è un multiplo della dimensione del blocco.
  • HMAC SHA-256 , con qualsiasi dimensione di 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 Keymaster. Keystore li fornisce nel software se l'implementazione hardware 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 la RSA

Controllo degli accessi tramite chiave

Le chiavi basate su hardware che non possono mai essere estratte dal dispositivo non forniscono molta sicurezza se un utente malintenzionato può utilizzarle 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 un "elenco di autorizzazioni" di coppie tag/valore. I tag di autorizzazione sono numeri interi a 32 bit e i valori sono di vario tipo. 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 sottostante Keystore modifica l'elenco per specificare alcune informazioni aggiuntive, ad esempio se la chiave dispone di protezione rollback, e restituisce un elenco di autorizzazioni "finale", codificato nel BLOB di chiavi restituito. Qualsiasi tentativo di utilizzare la chiave per qualsiasi operazione di crittografia fallisce se l'elenco di autorizzazioni finale viene modificato.

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

Keymaster 3 ha cambiato 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 nell'enum keymaster_purpose_t .

ENUM_REP : Uguale a ENUM , tranne per il fatto 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 .

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 : interi senza segno a 64 bit. Esempio: TAG::RSA_PUBLIC_EXPONENT

ULONG_REP : Uguale a 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. Si presuppone che una variabile di tipo BOOL sia "false" se la variabile non è presente e "true" se presente. Esempio: TAG::ROLLBACK_RESISTANT

BIGNUM : numeri interi di lunghezza arbitraria, espressi come array 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 rispettivamente tra applicazione del controllo dell'accesso mondiale sicuro e non sicuro o applicazione dell'hardware e del software.

Tutte le implementazioni:

  • Applicare 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, incluso l'ordinamento. Qualsiasi mancata corrispondenza provoca una diagnostica di errore.
  • Dichiarare le autorizzazioni i cui valori semantici vengono 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 sottoelenchi, hw_enforced e sw_enforced . L'hardware sicuro è responsabile dell'inserimento dei 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 siano applicate o meno dall'hardware sicuro.

Ad esempio, considera un'implementazione basata su TrustZone che non supporta la scadenza delle chiavi. È comunque possibile creare una chiave con una data di scadenza. L'elenco di autorizzazioni di tale 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 applicherà 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 di caratteristiche chiave troverà TAG::ORIGINATION_EXPIRE_DATETIME nell'elenco hw_enforced e i tentativi di utilizzare la chiave dopo la scadenza falliranno anche se il keystore viene in qualche modo sovvertito o bypassato .

Per ulteriori informazioni su come determinare se le chiavi sono supportate da hardware, vedere Attestazione della 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 , 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 scopi, espressi 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. Tieni presente 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 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 un hardware sicuro, TAG::ORIGIN con valore KeyOrigin::GENERATED verrà trovata nell'elenco hw_enforced delle caratteristiche della chiave, mentre una chiave importata in hardware sicuro avrà il valore KeyOrigin::IMPORTED .

Autenticazione utente

Le implementazioni Secure Keymaster non implementano l'autenticazione dell'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 sono specificati tramite due serie 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, e viene applicato 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 sicura per sbloccare l'utilizzo della chiave. Se ripetuta, la chiave può essere utilizzata se uno qualsiasi dei valori viene fornito in un token di autenticazione sicura.

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

  • NO_AUTHENTICATION_REQUIRED indica che non è richiesta l'autenticazione dell'utente, anche se la chiave può comunque essere utilizzata solo dalle app in esecuzione come utente specificato 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. Questo si applica solo alle operazioni con chiave privata/segreta. Le operazioni con chiave pubblica non richiedono l'autenticazione. I timeout non superano i riavvii; dopo un riavvio, tutte le chiavi "non vengono mai autenticate". Il timeout può essere impostato su un valore elevato per indicare che l'autenticazione è richiesta una volta per avvio (2^32 secondi corrispondono a ~136 anni; presumibilmente i dispositivi Android vengono riavviati più spesso).

Vincolante del cliente

L'associazione del client, l'associazione di una chiave con una particolare applicazione client, viene eseguita 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, garantendo solo che gli stessi BLOB presentati durante la generazione/importazione delle chiavi siano presentati per ogni utilizzo e siano identici byte per byte. I dati di associazione del client non vengono restituiti da Keymaster. Il chiamante deve saperlo per poter utilizzare la chiave.

Questa funzionalità non è esposta alle applicazioni.

Scadenza

Keystore supporta la limitazione dell'utilizzo delle chiavi in ​​base alla data. L'inizio di validità e le scadenze delle chiavi possono essere associati a una chiave e Keymaster si rifiuta di eseguire operazioni con le chiavi 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 "originazione" 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 esistente. 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 presuppone che la chiave in questione possa sempre essere utilizzata per decriptare/verificare i messaggi.

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

Radice di vincolo di fiducia

Il keystore richiede che le chiavi siano legate a una root of trust, che è una stringa di bit fornita all'hardware sicuro Keymaster durante l'avvio, preferibilmente dal bootloader. Questa bitstring è crittograficamente legata ad 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 lo stato di blocco viene modificato, nessuna delle chiavi protette da Keymaster create dal sistema precedente sarà utilizzabile, a meno che non venga ripristinata la radice di attendibilità precedente e un sistema 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.

Tasti autonomi

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 finché non è disponibile qualche altro componente del sistema mondiale non sicuro o protetto. L'HAL Keymaster 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 controllati per vedere se una chiave è autonoma. Al momento sono definiti solo due valori:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

Questa funzionalità non è esposta alle applicazioni.

Velocità

Una volta creato, la velocità di utilizzo massima può essere specificata con TAG::MIN_SECONDS_BETWEEN_OPS . Le implementazioni 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 per implementare i 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 scartata, le implementazioni hardware sicure "fail-safe", preferendo rifiutare tutte le operazioni 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 utilizzi per avvio con TAG::MAX_USES_PER_BOOT . Ciò richiede anche una tabella di tracciamento, che contenga almeno quattro chiavi e anch'essa a prova di guasto. Tieni presente che le applicazioni non saranno in grado di creare chiavi limitate all'avvio. Questa funzionalità non è esposta tramite Keystore ed è riservata alle operazioni di sistema.

Questa funzionalità 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 hardware di numeri casuali potrebbero non essere sempre completamente affidabili, Keymaster HAL fornisce un'interfaccia per consentire al client di fornire ulteriore entropia che verrà mescolata nel casuale numeri generati.

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

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