Funzioni Keymaster

Questa pagina fornisce dettagli per assistere gli implementatori di Keymaster Hardware Abstraction Layers (HAL). Copre ogni funzione nell'API e in quale versione di Keymaster è disponibile quella funzione e descrive l'implementazione predefinita. Per i tag, vedere la pagina Tag Keymaster .

Linee guida generali di attuazione

Le seguenti linee guida si applicano a tutte le funzioni nell'API.

Immettere i parametri del puntatore

Versione : 1, 2

I parametri del puntatore di input che non vengono utilizzati per una determinata chiamata possono essere NULL . Il chiamante non è tenuto a fornire segnaposto. Ad esempio, alcuni tipi e modalità di chiave potrebbero non utilizzare alcun valore dall'argomento inParams per iniziare , quindi il chiamante può impostare inParams su NULL o fornire un set di parametri vuoto. I chiamanti possono anche fornire parametri inutilizzati e i metodi Keymaster non dovrebbero generare errori.

Se un parametro di input richiesto è NULL, i metodi Keymaster dovrebbero restituire ErrorCode::UNEXPECTED_NULL_POINTER .

A partire da Keymaster 3, non ci sono parametri del puntatore. Tutti i parametri vengono passati per valore o riferimenti const.

Parametri del puntatore di uscita

Versione : 1, 2

Analogamente ai parametri del puntatore di input, i parametri del puntatore di output inutilizzati possono essere NULL . Se un metodo deve restituire dati in un parametro di output trovato NULL , dovrebbe restituire ErrorCode::OUTPUT_PARAMETER_NULL .

A partire da Keymaster 3, non ci sono parametri del puntatore. Tutti i parametri vengono passati per valore o riferimenti const.

Uso improprio dell'API

Versione : 1, 2, 3

Ci sono molti modi in cui i chiamanti possono fare richieste prive di senso o sciocche ma non tecnicamente sbagliate. In questi casi non è necessario che le implementazioni di Keymaster falliscano o emettano una diagnostica. L'uso di chiavi troppo piccole, la specifica di parametri di input irrilevanti, il riutilizzo di IV o nonces, la generazione di chiavi senza scopo (quindi inutili) e simili non dovrebbero essere diagnosticati dalle implementazioni. È necessario diagnosticare l'omissione dei parametri richiesti, la specifica di parametri obbligatori non validi ed errori simili.

È responsabilità delle app, del framework e del keystore Android garantire che le chiamate ai moduli Keymaster siano sensate e utili.

Funzioni

getHardwareFeatures

Versione : 3

Il nuovo metodo getHardwareFeatures espone ai client alcune importanti caratteristiche dell'hardware protetto sottostante. Il metodo non accetta argomenti e restituisce quattro valori, tutti booleani:

  • isSecure è true se le chiavi sono archiviate in un hardware sicuro (TEE, ecc.) e non lo lasciano mai.
  • supportsEllipticCurve è true se l'hardware supporta la crittografia della curva ellittica con le curve NIST (P-224, P-256, P-384 e P-521).
  • supportsSymmetricCryptography è true se l'hardware supporta la crittografia simmetrica, inclusi AES e HMAC.
  • supportsAttestation è true se l'hardware supporta la generazione di certificati di attestazione di chiave pubblica Keymaster, firmati con una chiave inserita in un ambiente sicuro.

Gli unici codici di errore che questo metodo può restituire sono ErrorCode:OK , ErrorCode::KEYMASTER_NOT_CONFIGURED o uno dei codici di errore che indicano una mancata comunicazione con l'hardware protetto.

getHardwareFeatures()
    generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
              bool supportsAttestation, bool supportsAllDigests, string keymasterName,
              string keymasterAuthorName);

configurare

Versione : 2

Questa funzione è stata introdotta in Keymaster 2 e deprecata in Keymaster 3, poiché queste informazioni sono disponibili nei file delle proprietà di sistema e le implementazioni del produttore leggono tali file durante l'avvio.

Configura keymaster. Questo metodo viene chiamato una volta dopo l'apertura del dispositivo e prima che venga utilizzato. Viene utilizzato per fornire KM_TAG_OS_VERSION e KM_TAG_OS_PATCHLEVEL al keymaster. Fino a quando questo metodo non viene chiamato, tutti gli altri metodi restituiscono KM_ERROR_KEYMASTER_NOT_CONFIGURED . I valori forniti da questo metodo vengono accettati da keymaster solo una volta per avvio. Le chiamate successive restituiscono KM_ERROR_OK , ma non fanno nulla.

Se l'implementazione del keymaster è in hardware sicuro e la versione del sistema operativo e i valori del livello di patch forniti non corrispondono ai valori forniti all'hardware sicuro dal bootloader (o se il bootloader non ha fornito valori), questo metodo restituisce KM_ERROR_INVALID_ARGUMENT e tutti gli altri i metodi continuano a restituire KM_ERROR_KEYMASTER_NOT_CONFIGURED .

keymaster_error_t (*configure)(const struct keymaster2_device* dev,
                               const keymaster_key_param_set_t* params);

addRngEntropy

Versione : 1, 2, 3

Questa funzione è stata introdotta in Keymaster 1 come add_rng_entropy e rinominata in Keymaster 3.

Aggiunge l'entropia fornita dal chiamante al pool utilizzato dall'implementazione di Keymaster 1 per generare numeri casuali, per chiavi, IV, ecc.

Le implementazioni di Keymaster devono mescolare in modo sicuro l'entropia fornita nel loro pool, che deve anche contenere entropia generata internamente da un generatore di numeri casuali hardware. Il missaggio deve essere gestito in modo che un utente malintenzionato che ha il controllo completo dei bit forniti da addRngEntropy o dei bit generati dall'hardware, ma non di entrambi, non abbia alcun vantaggio non trascurabile nel prevedere i bit generati dal pool di entropia.

Le implementazioni di Keymaster che tentano di stimare l'entropia nel loro pool interno presuppongono che i dati forniti da addRngEntropy non contengano entropia. Le implementazioni di Keymaster possono restituire ErrorCode::INVALID_INPUT_LENGTH se ricevono più di 2 KiB di dati in una singola chiamata.

generateKey

Versione : 1, 2, 3

Questa funzione è stata introdotta in Keymaster 1 come generate_key e rinominata in Keymaster 3.

Genera una nuova chiave crittografica, specificando le autorizzazioni associate, che sono permanentemente vincolate alla chiave. Le implementazioni di Keymaster rendono impossibile l'utilizzo di una chiave in qualsiasi modo non coerente con le autorizzazioni specificate in fase di generazione. Per quanto riguarda le autorizzazioni che l'hardware sicuro non può far rispettare, l'obbligo dell'hardware sicuro si limita a garantire che le autorizzazioni inapplicabili associate alla chiave non possano essere modificate, in modo che ogni chiamata a getKeyCharacteristics restituisca il valore originale. Inoltre, le caratteristiche restituite da generateKey assegna correttamente le autorizzazioni tra gli elenchi applicati dall'hardware e quelli applicati dal software. Vedere getKeyCharacteristics per maggiori dettagli.

I parametri forniti per generateKey dipendono dal tipo di chiave generata. Questa sezione riassume i tag necessari e facoltativi per ogni tipo di chiave. Tag::ALGORITMO è sempre necessario, per specificare il tipo.

Chiavi RSA

I seguenti parametri sono necessari per generare una chiave RSA.

  • Tag::KEY_SIZE specifica la dimensione del modulo pubblico, in bit. Se omesso, il metodo restituisce ErrorCode::UNSUPPORTED_KEY_SIZE . I valori supportati sono 1024, 2048, 3072 e 4096. I valori consigliati sono tutte le dimensioni chiave che sono un multiplo di 8.
  • Tag::RSA_PUBLIC_EXPONENT specifica il valore dell'esponente pubblico RSA. Se omesso, il metodo restituisce ErrorCode::INVALID_ARGUMENT . I valori supportati sono 3 e 65537. I valori consigliati sono tutti valori primi fino a 2^64.

I parametri seguenti non sono necessari per generare una chiave RSA, ma la creazione di una chiave RSA senza di essi produce una chiave inutilizzabile. Tuttavia, la funzione generateKey non restituisce un errore se questi parametri vengono omessi.

  • Tag::SCOPO specifica gli scopi consentiti. Tutti gli scopi devono essere supportati per le chiavi RSA, in qualsiasi combinazione.
  • Tag::DIGEST specifica gli algoritmi digest che possono essere utilizzati con la nuova chiave. Le implementazioni che non supportano tutti gli algoritmi digest devono accettare richieste di generazione di chiavi che includono digest non supportati. I digest non supportati devono essere inseriti nell'elenco "applicato dal software" nelle caratteristiche chiave restituite. Questo perché la chiave è utilizzabile con quegli altri digest, ma la digestione viene eseguita nel software. Quindi l'hardware viene chiamato per eseguire l'operazione con Digest::NONE .
  • Tag::PADDING specifica le modalità di riempimento che possono essere utilizzate con la nuova chiave. Le implementazioni che non supportano tutti gli algoritmi digest devono inserire PaddingMode::RSA_PSS e PaddingMode::RSA_OAEP nell'elenco delle caratteristiche chiave applicato dal software se vengono specificati algoritmi digest non supportati.

Chiavi ECDSA

Solo Tag::KEY_SIZE è necessario per generare una chiave ECDSA. Viene utilizzato per selezionare il gruppo EC. I valori supportati sono 224, 256, 384 e 521, che indicano rispettivamente le curve NIST p-224, p-256, p-384 e p521.

Tag::DIGEST è necessario anche per una chiave ECDSA utile, ma non è necessario per la generazione.

chiavi AES

Solo Tag::KEY_SIZE è necessario per generare una chiave AES. Se omesso, il metodo restituisce ErrorCode::UNSUPPORTED_KEY_SIZE . I valori supportati sono 128 e 256, con supporto opzionale per chiavi AES a 192 bit.

I seguenti parametri sono particolarmente rilevanti per le chiavi AES, ma non sono necessari per generarne una:

  • Tag::BLOCK_MODE specifica le modalità di blocco con cui è possibile utilizzare la nuova chiave.
  • Tag::PADDING specifica le modalità di riempimento che possono essere utilizzate. Questo è rilevante solo per le modalità BCE e CBC.

Se viene specificata la modalità di blocco GCM, fornire il Tag::MIN_MAC_LENGTH . Se omesso, il metodo restituisce ErrorCode::MISSING_MIN_MAC_LENGTH . Il valore del tag è un multiplo di 8 e compreso tra 96 ​​e 128.

chiavi HMAC

I seguenti parametri sono necessari per la generazione della chiave HMAC:

  • Tag::KEY_SIZE specifica la dimensione della chiave in bit. I valori inferiori a 64 e i valori che non sono multipli di 8 non sono supportati. Sono supportati tutti i multipli di 8, da 64 a 512. Possono essere supportati valori maggiori.
  • Tag::MIN_MAC_LENGTH specifica la lunghezza minima dei MAC che possono essere generati o verificati con questa chiave. Il valore è un multiplo di 8 e almeno 64.
  • Tag::DIGEST specifica l'algoritmo digest per la chiave. Viene specificato esattamente un digest, altrimenti restituisce ErrorCode::UNSUPPORTED_DIGEST . Se il digest non è supportato dal trustlet, restituire ErrorCode::UNSUPPORTED_DIGEST .

Caratteristiche chiave

Se l'argomento delle caratteristiche non è NULL, generateKey restituisce le caratteristiche della chiave appena generata suddivise in modo appropriato in elenchi applicati dall'hardware e dal software. Vedere getKeyCharacteristics per una descrizione di quali caratteristiche vanno in quale elenco. Le caratteristiche restituite includono tutti i parametri specificati per la generazione della chiave, ad eccezione di Tag::APPLICATION_ID e Tag::APPLICATION_DATA . Se questi tag sono stati inclusi nei parametri chiave, vengono rimossi dalle caratteristiche restituite in modo che non sia possibile trovarne i valori esaminando il BLOB di chiavi restituito. Tuttavia, sono vincolati crittograficamente al BLOB di chiavi, quindi se non vengono forniti i valori corretti quando viene utilizzata la chiave, l'utilizzo non riesce. Allo stesso modo, Tag::ROOT_OF_TRUST è crittograficamente vincolato alla chiave, ma potrebbe non essere specificato durante la creazione o l'importazione della chiave e non viene mai restituito.

Oltre ai tag forniti, il trustlet aggiunge anche Tag::ORIGIN , con il valore KeyOrigin::GENERATED , e se la chiave è resistente al rollback,

Etichetta::ROLLBACK_RESISTANT .

Resistenza al rollio

La resistenza al rollback significa che una volta eliminata una chiave con deleteKey o deleteAllKeys , l'hardware sicuro garantisce che non sarà mai più utilizzabile. Le implementazioni senza resistenza al rollback in genere restituiscono al chiamante il materiale della chiave generato o importato come un BLOB di chiavi, un modulo crittografato e autenticato. Quando keystore elimina il BLOB di chiavi, la chiave scompare, ma un utente malintenzionato che è riuscito in precedenza a recuperare il materiale della chiave può potenzialmente ripristinarlo sul dispositivo.

Una chiave è resistente al rollback se l'hardware protetto garantisce che le chiavi eliminate non possano essere ripristinate in un secondo momento. Ciò viene generalmente eseguito archiviando ulteriori metadati chiave in una posizione attendibile che non può essere manipolata da un utente malintenzionato. Sui dispositivi mobili, il meccanismo utilizzato per questo è solitamente Replay Protected Memory Blocks (RPMB). Poiché il numero di chiavi che possono essere create è sostanzialmente illimitato e lo spazio di archiviazione attendibile utilizzato per la resistenza al rollback può avere dimensioni limitate, questo metodo deve avere esito positivo anche se non è possibile fornire la resistenza al rollback per la nuova chiave. In tal caso, Tag::ROLLBACK_RESISTANT non dovrebbe essere aggiunto alle caratteristiche chiave.

getKeyCharacteristics

Versione : 1, 2, 3

Questa funzione è stata introdotta in Keymaster 1 come get_key_characteristics e rinominata in Keymaster 3.

Restituisce parametri e autorizzazioni associati alla chiave fornita, divisi in due set: hardware-enforced e software-enforced. La descrizione qui si applica ugualmente agli elenchi delle caratteristiche chiave restituiti da generateKey e importKey .

Se Tag::APPLICATION_ID è stato fornito durante la generazione o l'importazione della chiave, lo stesso valore viene fornito a questo metodo nell'argomento clientId . In caso contrario, il metodo restituisce ErrorCode::INVALID_KEY_BLOB . Allo stesso modo, se Tag::APPLICATION_DATA è stato fornito durante la generazione o l'importazione, lo stesso valore viene fornito a questo metodo nell'argomento appData .

Le caratteristiche restituite da questo metodo descrivono completamente il tipo e l'utilizzo della chiave specificata.

La regola generale per decidere se un determinato tag appartiene all'elenco applicato dall'hardware o dal software è che se il significato del tag è completamente assicurato dall'hardware sicuro, questo viene imposto dall'hardware. Altrimenti, è un software imposto. Di seguito è riportato un elenco di tag specifici la cui corretta allocazione potrebbe non essere chiara:

  • Tag::ALGORITHM , Tag::KEY_SIZE e Tag::RSA_PUBLIC_EXPONENT sono proprietà intrinseche della chiave. Per qualsiasi chiave protetta dall'hardware, questi tag saranno nell'elenco di applicazione dell'hardware.
  • Tag::I valori DIGEST supportati dall'hardware protetto vengono inseriti nell'elenco dei supporti hardware. I digest non supportati vanno nell'elenco dei software supportati.
  • Tag::I valori di PADDING generalmente vanno nell'elenco dei supporti hardware, a meno che non vi sia la possibilità che una specifica modalità di riempimento debba essere eseguita dal software. In tal caso, vanno nell'elenco applicato dal software. Tale possibilità si presenta per le chiavi RSA che consentono il riempimento PSS o OAEP con algoritmi digest che non sono supportati dall'hardware sicuro.
  • Tag::USER_SECURE_ID e Tag::USER_AUTH_TYPE sono applicati dall'hardware solo se l'autenticazione utente è applicata dall'hardware. A tal fine, il trustlet Keymaster e il relativo trustlet di autenticazione devono essere entrambi protetti e condividere una chiave HMAC segreta utilizzata per firmare e convalidare i token di autenticazione. Per i dettagli, vedere la pagina Autenticazione .
  • Tag::ACTIVE_DATETIME , Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME i tag richiedono l'accesso a un orologio da parete verificabilmente corretto. La maggior parte dell'hardware sicuro ha accesso solo alle informazioni sull'ora fornite dal sistema operativo non sicuro, il che significa che i tag sono applicati dal software.
  • Tag::ORIGIN è sempre nell'elenco hardware per le chiavi associate all'hardware. La sua presenza in quell'elenco è il modo in cui i livelli più alti determinano che una chiave è supportata dall'hardware.

importKey

Versione : 1, 2, 3

Questa funzione è stata introdotta in Keymaster 1 come import_key e rinominata in Keymaster 3.

Importa il materiale chiave nell'hardware Keymaster. I parametri di definizione della chiave e le caratteristiche di output vengono gestiti come per generateKey , con le seguenti eccezioni:

  • Tag::KEY_SIZE e Tag::RSA_PUBLIC_EXPONENT (solo per chiavi RSA) non sono necessari nei parametri di input. Se non fornito, il trustlet deduce i valori dal materiale chiave fornito e aggiunge tag e valori appropriati alle caratteristiche chiave. Se i parametri vengono forniti, il trustlet li convalida rispetto al materiale della chiave. In caso di mancata corrispondenza, il metodo restituisce ErrorCode::IMPORT_PARAMETER_MISMATCH .
  • Il Tag::ORIGIN restituito ha lo stesso valore di KeyOrigin::IMPORTED .

exportKey

Versione : 1, 2, 3

Questa funzione è stata introdotta in Keymaster 1 come export_key e rinominata in Keymaster 3.

Esporta una chiave pubblica da una coppia di chiavi Keymaster RSA o EC.

Se Tag::APPLICATION_ID è stato fornito durante la generazione o l'importazione della chiave, lo stesso valore viene fornito a questo metodo nell'argomento clientId . In caso contrario, il metodo restituisce ErrorCode::INVALID_KEY_BLOB . Allo stesso modo, se Tag::APPLICATION_DATA è stato fornito durante la generazione o l'importazione, lo stesso valore viene fornito a questo metodo nell'argomento appData .

deleteKey

Versione : 1, 2, 3

Questa funzione è stata introdotta in Keymaster 1 come delete_key e rinominata in Keymaster 3.

Elimina la chiave fornita. Questo metodo è facoltativo ed è implementato solo dai moduli Keymaster che forniscono resistenza al rollback.

deleteAllKeys

Versione : 1, 2, 3

Questa funzione è stata introdotta in Keymaster 1 come delete_all_keys e rinominata in Keymaster 3.

Elimina tutte le chiavi. Questo metodo è facoltativo ed è implementato solo dai moduli Keymaster che forniscono resistenza al rollback.

destroyAttestationIds

Versione : 3

Il metodo destroyAttestationIds() viene utilizzato per disabilitare in modo permanente la nuova funzionalità di attestazione ID (facoltativa, ma altamente consigliata). Se il TEE non ha modo di garantire che l'attestazione ID sia disabilitata in modo permanente dopo la chiamata di questo metodo, l'attestazione ID non deve essere implementata affatto, nel qual caso questo metodo non fa nulla e restituisce ErrorCode::UNIMPLEMENTED . Se l'attestazione ID è supportata, questo metodo deve essere implementato e deve disabilitare in modo permanente tutti i futuri tentativi di attestazione ID. Il metodo può essere chiamato un numero qualsiasi di volte. Se l'attestazione ID è già disabilitata in modo permanente, il metodo non esegue alcuna operazione e restituisce ErrorCode::OK .

Gli unici codici di errore che questo metodo può restituire sono ErrorCode::UNIMPLEMENTED (se l'attestazione ID non è supportata), ErrorCode:OK , ErrorCode::KEYMASTER_NOT_CONFIGURED o uno dei codici di errore che indicano una mancata comunicazione con l'hardware protetto.

inizio

Versione : 1, 2, 3

Avvia un'operazione di crittografia, usando la chiave specificata, per lo scopo specificato, con i parametri specificati (a seconda dei casi) e restituisce un handle dell'operazione che viene utilizzato con update e finish per completare l'operazione. L'handle dell'operazione viene utilizzato anche come token "challenge" nelle operazioni autenticate e per tali operazioni è incluso nel campo challenge del token di autenticazione.

Un'implementazione Keymaster supporta almeno 16 operazioni simultanee. Keystore ne utilizza fino a 15, lasciandone uno che vold può utilizzare per la crittografia della password. Quando Keystore ha 15 operazioni in corso ( begin è stato chiamato, ma finish o abort non sono stati ancora chiamati) e riceve una richiesta di inizio 16, chiama abort sull'operazione utilizzata meno di recente per ridurre il numero di operazioni attive alle 14 prima di chiamare begin ad avviare la nuova operazione richiesta.

Se Tag::APPLICATION_ID o Tag::APPLICATION_DATA sono stati specificati durante la generazione o l'importazione della chiave, le chiamate per begin includono quei tag con i valori originariamente specificati nell'argomento inParams di questo metodo.

Esecuzione dell'autorizzazione

Durante questo metodo, le seguenti autorizzazioni di chiave vengono applicate dal trustlet se l'implementazione le ha collocate nelle caratteristiche "applicate dall'hardware" e se l'operazione non è un'operazione a chiave pubblica. Le operazioni con chiave pubblica, ovvero KeyPurpose::ENCRYPT e KeyPurpose::VERIFY , con chiavi RSA o EC, possono avere esito positivo anche se i requisiti di autorizzazione non sono soddisfatti.

  • Tag::PURPOSE : Lo scopo specificato nella chiamata begin() deve corrispondere a uno degli scopi nelle autorizzazioni della chiave, a meno che l'operazione richiesta non sia un'operazione di chiave pubblica. Se lo scopo specificato non corrisponde e l'operazione non è un'operazione di chiave pubblica, begin restituirà ErrorCode::UNSUPPORTED_PURPOSE . Le operazioni a chiave pubblica sono operazioni di crittografia o verifica asimmetriche.
  • Tag::ACTIVE_DATETIME può essere applicato solo se è disponibile un'origine dell'ora UTC affidabile. Se la data e l'ora correnti sono precedenti al valore del tag, il metodo restituisce ErrorCode::KEY_NOT_YET_VALID .
  • Tag::ORIGINATION_EXPIRE_DATETIME può essere applicato solo se è disponibile un'origine dell'ora UTC attendibile. Se la data e l'ora correnti sono successive al valore del tag e lo scopo è KeyPurpose::ENCRYPT o KeyPurpose::SIGN , il metodo restituisce ErrorCode::KEY_EXPIRED .
  • Tag::USAGE_EXPIRE_DATETIME può essere applicato solo se è disponibile un'origine dell'ora UTC affidabile. Se la data e l'ora correnti sono successive al valore del tag e lo scopo è KeyPurpose::DECRYPT o KeyPurpose::VERIFY , il metodo restituisce ErrorCode::KEY_EXPIRED .
  • Tag::MIN_SECONDS_BETWEEN_OPS viene confrontato con un timer relativo attendibile che indica l'ultimo utilizzo della chiave. Se l'ora dell'ultimo utilizzo più il valore del tag è inferiore all'ora corrente, il metodo restituisce ErrorCode::KEY_RATE_LIMIT_EXCEEDED . Vedere la descrizione del tag per importanti dettagli sull'implementazione.
  • Tag::MAX_USES_PER_BOOT viene confrontato con un contatore sicuro che tiene traccia degli usi della chiave dal momento dell'avvio. Se il conteggio degli utilizzi precedenti supera il valore del tag, il metodo restituisce ErrorCode::KEY_MAX_OPS_EXCEEDED .
  • Tag::USER_SECURE_ID viene imposto da questo metodo solo se la chiave ha anche Tag::AUTH_TIMEOUT . Se la chiave ha entrambi, questo metodo deve ricevere un Tag::AUTH_TOKEN valido in inParams . Affinché il token di autenticazione sia valido, devono essere vere tutte le seguenti condizioni:
    • Il campo HMAC viene convalidato correttamente.
    • Almeno uno dei valori Tag::USER_SECURE_ID della chiave corrisponde ad almeno uno dei valori di Secure ID nel token.
    • La chiave ha un Tag::USER_AUTH_TYPE che corrisponde al tipo di autenticazione nel token.

    Se una di queste condizioni non viene soddisfatta, il metodo restituisce ErrorCode::KEY_USER_NOT_AUTHENTICATED .

  • Tag::CALLER_NONCE consente al chiamante di specificare un nonce o un vettore di inizializzazione (IV). Se la chiave non ha questo tag, ma il chiamante ha fornito Tag::NONCE a questo metodo, viene restituito ErrorCode::CALLER_NONCE_PROHIBITED .
  • Tag::BOOTLOADER_ONLY specifica che solo il bootloader può utilizzare la chiave. Se questo metodo viene chiamato con una chiave di solo bootloader al termine dell'esecuzione del bootloader, restituisce ErrorCode::INVALID_KEY_BLOB .

Chiavi RSA

Tutte le operazioni con la chiave RSA specificano esattamente una modalità di riempimento in inParams . Se non specificato o specificato più di una volta, il metodo restituisce ErrorCode::UNSUPPORTED_PADDING_MODE .

Le operazioni di firma e verifica RSA richiedono un digest, così come le operazioni di crittografia e decrittografia RSA con la modalità di riempimento OAEP. Per questi casi, il chiamante specifica esattamente un digest in inParams . Se non specificato o specificato più di una volta, il metodo restituisce ErrorCode::UNSUPPORTED_DIGEST .

Le operazioni con chiave privata ( KeyPurpose::DECYPT e KeyPurpose::SIGN ) richiedono l'autorizzazione di digest e riempimento, il che significa che le autorizzazioni della chiave devono contenere i valori specificati. In caso contrario, il metodo restituisce ErrorCode::INCOMPATIBLE_DIGEST o ErrorCode::INCOMPATIBLE_PADDING , a seconda dei casi. Le operazioni con chiave pubblica ( KeyPurpose::ENCRYPT e KeyPurpose::VERIFY ) sono consentite con digest o padding non autorizzati.

Ad eccezione di PaddingMode::NONE , tutte le modalità di riempimento RSA sono applicabili solo a determinati scopi. In particolare, PaddingMode::RSA_PKCS1_1_5_SIGN e PaddingMode::RSA_PSS supportano solo la firma e la verifica, mentre PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT e PaddingMode::RSA_OAEP supportano solo la crittografia e la decrittografia. Il metodo restituisce ErrorCode::UNSUPPORTED_PADDING_MODE se la modalità specificata non supporta lo scopo specificato.

Esistono alcune importanti interazioni tra le modalità di riempimento e i digest:

  • PaddingMode::NONE indica che viene eseguita un'operazione RSA "grezza". Se si firma o si verifica, Digest::NONE è specificato per il digest. Non è necessario alcun digest per la crittografia o la decrittazione non riempita.
  • PaddingMode::RSA_PKCS1_1_5_SIGN riempimento richiede un digest. Il digest potrebbe essere Digest::NONE , nel qual caso l'implementazione Keymaster non può creare una struttura di firma PKCS#1 v1.5 corretta, perché non può aggiungere la struttura DigestInfo. Invece, l'implementazione costruisce 0x00 || 0x01 || PS || 0x00 || M , dove M è il messaggio fornito e PS è la stringa di riempimento. La dimensione della chiave RSA deve essere almeno 11 byte maggiore del messaggio, altrimenti il ​​metodo restituisce ErrorCode::INVALID_INPUT_LENGTH .
  • PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT riempimento non richiede un digest.
  • Il riempimento PaddingMode::RSA_PSS richiede un digest, che potrebbe non essere Digest::NONE . Se viene specificato Digest::NONE , il metodo restituisce ErrorCode::INCOMPATIBLE_DIGEST . Inoltre, la dimensione della chiave RSA deve essere almeno 2 + D byte maggiore della dimensione di output del digest, dove D è la dimensione del digest, in byte. In caso contrario, il metodo restituisce ErrorCode::INCOMPATIBLE_DIGEST . La dimensione del sale è D.
  • PaddingMode::RSA_OAEP padding richiede un digest, che potrebbe non essere Digest::NONE . Se viene specificato Digest::NONE , il metodo restituisce ErrorCode::INCOMPATIBLE_DIGEST .

Chiavi EC

Le operazioni con la chiave EC specificano esattamente una modalità di riempimento in inParams . Se non specificato o specificato più di una volta, il metodo restituisce ErrorCode::UNSUPPORTED_PADDING_MODE .

Le operazioni con chiave privata ( KeyPurpose::SIGN ) richiedono l'autorizzazione di digest e riempimento, il che significa che le autorizzazioni della chiave devono contenere i valori specificati. In caso contrario, restituire ErrorCode::INCOMPATIBLE_DIGEST . Le operazioni con chiave pubblica ( KeyPurpose::VERIFY ) sono consentite con digest o padding non autorizzati.

chiavi AES

Le operazioni con i tasti AES specificano esattamente una modalità di blocco e una modalità di riempimento in inParams . Se uno dei valori non è specificato o è specificato più di una volta, restituire ErrorCode::UNSUPPORTED_BLOCK_MODE o ErrorCode::UNSUPPORTED_PADDING_MODE . Le modalità specificate devono essere autorizzate dalla chiave, altrimenti il ​​metodo restituisce ErrorCode::INCOMPATIBLE_BLOCK_MODE o ErrorCode::INCOMPATIBLE_PADDING_MODE .

Se la modalità blocco è BlockMode::GCM , inParams specifica Tag::MAC_LENGTH e il valore specificato è un multiplo di 8 che non è maggiore di 128 o minore del valore di Tag::MIN_MAC_LENGTH nelle autorizzazioni della chiave. Per lunghezze MAC maggiori di 128 o non multipli di 8, restituire ErrorCode::UNSUPPORTED_MAC_LENGTH . Per valori inferiori alla lunghezza minima della chiave, restituire ErrorCode::INVALID_MAC_LENGTH .

Se la modalità di blocco è BlockMode::GCM o BlockMode::CTR , la modalità di riempimento specificata deve essere PaddingMode::NONE . Per BlockMode::ECB o BlockMode::CBC , la modalità potrebbe essere PaddingMode::NONE o PaddingMode::PKCS7 . Se la modalità di riempimento non soddisfa queste condizioni, restituire ErrorCode::INCOMPATIBLE_PADDING_MODE .

Se la modalità blocco è BlockMode::CBC , BlockMode::CTR o BlockMode::GCM , è necessario un vettore di inizializzazione o nonce. Nella maggior parte dei casi, i chiamanti non dovrebbero fornire un IV o un nonce. In tal caso, l'implementazione Keymaster genera un IV o nonce casuale e lo restituisce tramite Tag:: NOCE in outParams . CBC e CTR IV sono 16 byte. I nonce GCM sono 12 byte. Se le autorizzazioni della chiave contengono Tag::CALLER_NONCE , il chiamante può fornire un IV/nonce con Tag::NONCE in inParams . Se viene fornito un nonce quando Tag::CALLER_NONCE non è autorizzato, restituire ErrorCode::CALLER_NONCE_PROHIBITED . Se non viene fornito un nonce quando Tag::CALLER_NONCE è autorizzato, generare un IV/nonce casuale.

chiavi HMAC

Le operazioni con la chiave HMAC specificano Tag::MAC_LENGTH in inParams . Il valore specificato deve essere un multiplo di 8 che non sia maggiore della lunghezza del digest o minore del valore di Tag::MIN_MAC_LENGTH nelle autorizzazioni della chiave. Per lunghezze MAC maggiori della lunghezza del digest o non multipli di 8, restituire ErrorCode::UNSUPPORTED_MAC_LENGTH . Per valori inferiori alla lunghezza minima della chiave, restituire ErrorCode::INVALID_MAC_LENGTH .

aggiornare

Versione : 1, 2, 3

Fornisce i dati da elaborare in un'operazione in corso iniziata con begin . L'operazione è specificata dal parametro operationHandle .

Per fornire una maggiore flessibilità per la gestione del buffer, le implementazioni di questo metodo hanno la possibilità di consumare meno dati di quelli forniti. Il chiamante è responsabile del loop per alimentare il resto dei dati nelle chiamate successive. La quantità di input consumata viene restituita nel parametro inputConsumed . Le implementazioni consumano sempre almeno un byte, a meno che l'operazione non possa accettarne più; se vengono forniti più di zero byte e vengono consumati zero byte, i chiamanti considerano questo un errore e interrompono l'operazione.

Le implementazioni possono anche scegliere quanti dati restituire, a seguito dell'aggiornamento. Questo è rilevante solo per le operazioni di crittografia e decrittografia, perché la firma e la verifica non restituiscono dati fino al termine . Restituire i dati il ​​prima possibile, anziché memorizzarli nel buffer.

Gestione degli errori

Se questo metodo restituisce un codice di errore diverso da ErrorCode::OK , l'operazione viene interrotta e l'handle dell'operazione viene invalidato. Qualsiasi uso futuro dell'handle, con questo metodo, finish o abort , restituisce ErrorCode::INVALID_OPERATION_HANDLE .

Esecuzione dell'autorizzazione

L'applicazione dell'autorizzazione della chiave viene eseguita principalmente all'inizio . L'unica eccezione è il caso in cui la chiave ha:

In questo caso, la chiave richiede un'autorizzazione per operazione e il metodo di aggiornamento riceve un Tag::AUTH_TOKEN nell'argomento inParams . HMAC verifica che il token sia valido e contenga un ID utente sicuro corrispondente, corrisponda al Tag::USER_AUTH_TYPE della chiave e contenga l'handle dell'operazione corrente nel campo challenge. Se queste condizioni non sono soddisfatte, restituisci ErrorCode::KEY_USER_NOT_AUTHENTICATED .

Il chiamante fornisce il token di autenticazione a ogni chiamata per l' aggiornamento e il completamento . L'implementazione deve convalidare il token solo una volta, se lo preferisce.

Chiavi RSA

Per le operazioni di firma e verifica con Digest::NONE , questo metodo accetta l'intero blocco da firmare o verificare in un unico aggiornamento. Potrebbe non consumare solo una parte del blocco. Tuttavia, se il chiamante sceglie di fornire i dati in più aggiornamenti, questo metodo lo accetta. Se il chiamante fornisce più dati da firmare di quelli che possono essere utilizzati (la lunghezza dei dati supera la dimensione della chiave RSA), restituire ErrorCode::INVALID_INPUT_LENGTH .

Chiavi ECDSA

Per le operazioni di firma e verifica con Digest::NONE , questo metodo accetta l'intero blocco da firmare o verificare in un unico aggiornamento. Questo metodo potrebbe non consumare solo una parte del blocco.

Tuttavia, se il chiamante sceglie di fornire i dati in più aggiornamenti, questo metodo lo accetta. Se il chiamante fornisce più dati da firmare di quelli che possono essere utilizzati, i dati vengono troncati automaticamente. (Ciò differisce dalla gestione dei dati in eccesso forniti in operazioni RSA simili. Il motivo è la compatibilità con i client legacy.)

chiavi AES

La modalità AES GCM supporta i "dati di autenticazione associati", forniti tramite il tag Tag::ASSOCIATED_DATA nell'argomento inParams . I dati associati possono essere forniti in chiamate ripetute (importante se i dati sono troppo grandi per essere inviati in un unico blocco) ma precedono sempre i dati da crittografare o decifrare. Una chiamata di aggiornamento può ricevere sia i dati associati che i dati da crittografare/decodificare, ma gli aggiornamenti successivi potrebbero non includere i dati associati. Se il chiamante fornisce dati associati a una chiamata di aggiornamento dopo una chiamata che include dati da crittografare/decrittografare, restituire ErrorCode::INVALID_TAG .

Per la crittografia GCM, il tag viene aggiunto al testo cifrato da finish . Durante la decrittazione, l'ultimo Tag::MAC_LENGTH byte dei dati forniti all'ultima chiamata di aggiornamento è il tag. Poiché una determinata chiamata di aggiornamento non può sapere se è l'ultima chiamata, elabora tutto tranne la lunghezza del tag e memorizza nel buffer i possibili dati del tag durante finish .

finire

Versione : 1, 2, 3

Termina un'operazione in corso iniziata con begin , elaborando tutti i dati non ancora elaborati forniti dagli aggiornamenti .

This method is the last one called in an operation, so all processed data is returned.

Whether it completes successfully or returns an error, this method finalizes the operation and therefore invalidates the provided operation handle. Any future use of the handle, with this method or update or abort , returns ErrorCode::INVALID_OPERATION_HANDLE .

Signing operations return the signature as the output. Verification operations accept the signature in the signature parameter, and return no output.

Authorization enforcement

Key authorization enforcement is performed primarily in begin . The one exception is the case where the key has:

In this case, the key requires an authorization per operation, and the update method receives a Tag::AUTH_TOKEN in the inParams argument. HMAC verifies that the token is valid and contains a matching secure user ID, matches the key's Tag::USER_AUTH_TYPE , and contains the operation handle of the current operation in the challenge field. If these conditions aren't met, return ErrorCode::KEY_USER_NOT_AUTHENTICATED .

The caller provides the authentication token to every call to update and finish . The implementation need only validate the token once if it prefers.

RSA keys

Some additional requirements, depending on the padding mode:

  • PaddingMode::NONE . For unpadded signing and encryption operations, if the provided data is shorter than the key, the data is be zero-padded on the left before signing/encryption. If the data is the same length as the key, but numerically larger, return ErrorCode::INVALID_ARGUMENT . For verification and decryption operations, the data must be exactly as long as the key. Otherwise, return ErrorCode::INVALID_INPUT_LENGTH.
  • PaddingMode::RSA_PSS . For PSS-padded signature operations, the PSS salt is the size of the message digest and randomly generated. The digest specified with Tag::DIGEST in inputParams on begin is used as the PSS digest algorithm, and as the MGF1 digest algorithm.
  • PaddingMode::RSA_OAEP . The digest specified with Tag::DIGEST in inputParams on begin is used as the OAEP digest algorithm, and SHA1 is used as the MGF1 digest algorithm.

ECDSA keys

If the data provided for unpadded signing or verification is too long, truncate it.

AES keys

Some additional conditions, depending on block mode:

  • BlockMode::ECB or BlockMode::CBC . If padding is PaddingMode::NONE and the data length is not a multiple of the AES block size, return ErrorCode::INVALID_INPUT_LENGTH . If padding is PaddingMode::PKCS7 , pad the data per the PKCS#7 specification. Note that PKCS#7 recommends adding an additional padding block if the data is a multiple of the block length.
  • BlockMode::GCM . During encryption, after processing all plaintext, compute the tag ( Tag::MAC_LENGTH bytes) and append it to the returned ciphertext. During decryption, process the last Tag::MAC_LENGTH bytes as the tag. If tag verification fails, return ErrorCode::VERIFICATION_FAILED .

abort

Version : 1, 2, 3

Aborts the in-progress operation. After the call to abort, return ErrorCode::INVALID_OPERATION_HANDLE for any subsequent use of the provided operation handle with update , finish , or abort .

get_supported_algorithms

Version : 1

Returns the list of algorithms supported by the Keymaster hardware implementation. A software implementation returns an empty list; a hybrid implementation returns a list containing only the algorithms that are supported by hardware.

Keymaster 1 implementations support RSA, EC, AES and HMAC.

get_supported_block_modes

Version : 1

Returns the list of AES block modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

For RSA, EC and HMAC, which are not block ciphers, the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE .

Keymaster 1 implementations support ECB, CBC, CTR and GCM for AES encryption and decryption.

get_supported_padding_modes

Version : 1

Returns the list of padding modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

HMAC and EC have no notion of padding so the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE .

For RSA, Keymaster 1 implementations support:

  • Unpadded encryption, decryption, signing and verification. For unpadded encryption and signing, if the message is shorter than the public modulus, implementations must left-pad it with zeros. For unpadded decryption and verification, the input length must match the public modulus size.
  • PKCS#1 v1.5 encryption and signing padding modes
  • PSS with a minimum salt length of 20
  • OAEP

For AES in ECB and CBC modes, Keymaster 1 implementations support no padding and PKCS#7-padding. CTR and GCM modes support only no padding.

get_supported_digests

Version : 1

Returns the list of digest modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

No AES modes support or require digesting, so the method returns an empty list for valid purposes.

Keymaster 1 implementations can implement a subset of the defined digests. Implementations provide SHA-256 and can provide MD5, SHA1, SHA-224, SHA-256, SHA384 and SHA512 (the full set of defined digests).

get_supported_import_formats

Version : 1

Returns the list of import formats supported by the Keymaster hardware implementation of a specified algorithm.

Keymaster 1 implementations support the PKCS#8 format (without password protection) for importing RSA and EC key pairs, and support RAW import of AES and HMAC key material.

get_supported_export_formats

Version : 1

Returns the list of export formats supported by the Keymaster hardware implementation of a specified algorithm.

Keymaster1 implementations support the X.509 format for exporting RSA and EC public keys. Export of private keys or asymmetric keys is not supported.

Historical functions

Keymaster 0

The following functions belong to the original Keymaster 0 definition. They were present in Keymaster 1 struct keymaster1_device_t. However, in Keymaster 1.0 they were not implemented, and their function pointers were set to NULL.

  • generate_keypair
  • import_keypair
  • get_keypair_public
  • delete_keypair
  • delete_all
  • sign_data
  • Verify_data

Keymaster 1

The following functions belong to the Keymaster 1 definition, but were removed in Keymaster 2, along with the Keymaster 0 functions listed above.

  • get_supported_algorithms
  • get_supported_block_modes
  • get_supported_padding_modes
  • get_supported_digests
  • get_supported_import_formats
  • get_supported_export_formats

Keymaster 2

The following functions belong to the Keymaster 2 definition, but were removed in Keymaster 3, along with the Keymaster 1 functions listed above.

  • configure