Questa pagina fornisce dettagli per aiutare gli implementatori di Keymaster Hardware Abstraction Layers (HAL). Copre ogni funzione dell'API e la versione di Keymaster in cui è disponibile la funzione, nonché descrive l'implementazione predefinita. Per i tag, consulta la pagina Tag Keymaster.
Linee guida generali di implementazione
Le seguenti linee guida si applicano a tutte le funzioni dell'API.
Parametri del cursore di input
Versione: 1, 2
I parametri del cursore di input che non vengono utilizzati per una determinata chiamata potrebbero essere
NULL
. L'utente che chiama non è tenuto a fornire segnaposto.
Ad esempio, alcuni tipi e modalità di chiave potrebbero non utilizzare alcun valore dell'argomento inParams
in begin, quindi il chiamante potrebbe impostare inParams
su NULL
o fornire un set di parametri vuoto. I chiamanti possono anche fornire parametri inutilizzati e i metodi Keymaster non devono generare errori.
Se un parametro di input obbligatorio è NULL, i metodi Keymaster devono restituire ErrorCode::UNEXPECTED_NULL_POINTER
.
A partire da Keymaster 3, non sono presenti parametri del cursore. Tutti i parametri vengono passati per valore o come riferimenti const.
Parametri del puntatore di output
Versione: 1, 2
Analogamente ai parametri del puntatore di input, i parametri del puntatore di output non utilizzati
potrebbero essere NULL
. Se un metodo deve restituire dati in un parametro di output che risulta essere NULL
, deve restituire ErrorCode::OUTPUT_PARAMETER_NULL
.
A partire da Keymaster 3, non sono disponibili parametri puntatore. Tutti i parametri vengono passati dai riferimenti value o const.
Uso improprio dell'API
Versione: 1, 2, 3
Esistono molti modi in cui gli utenti possono effettuare richieste che non hanno senso o sono sciocche, ma non tecnicamente errate. Le implementazioni di Keymaster non sono obbligatoriamente destinate a fallire in questi casi o a emettere una diagnostica. L'utilizzo di chiavi troppo piccole, la specifica di parametri di input irrilevanti, il riutilizzo di IV o nonce, la generazione di chiavi senza scopo (quindi inutili) e simili non deve essere diagnosticato dalle implementazioni. È necessario diagnosticare l'omissione di parametri obbligatori, 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
mostra ai clienti alcune caratteristiche importanti dell'hardware sicuro sottostante.
Il metodo non accetta argomenti e restituisce quattro valori, tutti booleani:
isSecure
ètrue
se le chiavi sono archiviate in hardware sicuro (TEE ecc.) e non vengono mai trasferite.supportsEllipticCurve
ètrue
se l'hardware supporta la crittografia con curve ellittiche 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 della 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 un errore di comunicazione con l'hardware sicuro.
getHardwareFeatures() generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography, bool supportsAttestation, bool supportsAllDigests, string keymasterName, string keymasterAuthorName);
configura
Versione: 2
Questa funzione è stata introdotta in Keymaster 2 e ritirata in Keymaster 3, poiché queste informazioni sono disponibili nei file delle proprietà di sistema e le implementazioni del produttore leggono questi file durante l'avvio.
Configura Keymaster. Questo metodo viene chiamato una volta aperto il dispositivo
e prima che venga utilizzato. Viene utilizzato per fornire
KM_TAG_OS_VERSION e
KM_TAG_OS_PATCHLEVEL a
keymaster. Fino a quando non viene chiamato questo metodo, tutti gli altri metodi restituiscono
KM_ERROR_KEYMASTER_NOT_CONFIGURED
. I valori forniti da questo metodo vengono accettati da Keymaster una sola volta per avvio. Le chiamate
successive restituiscono KM_ERROR_OK
, ma non fanno nulla.
Se l'implementazione keymaster è in hardware protetto e i valori di versione del sistema operativo e
livello di patch forniti non corrispondono ai valori forniti all'hardware protetto
dal bootloader (o se il bootloader non ha fornito valori), questo metodo restituisce KM_ERROR_INVALID_ARGUMENT
e tutti gli altri
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 dall'utente al pool utilizzato dall'implementazione di Keymaster 1 per generare numeri casuali, chiavi, IV e così via.
Le implementazioni di Keymaster devono combinare in modo sicuro l'entropia fornita nel pool, che deve anche contenere l'entropia generata internamente da un generatore di numeri casuali hardware.
La combinazione deve essere gestita in modo che un utente malintenzionato che abbia il controllo completo
dei bit forniti da addRngEntropy
o di quelli generati dall'hardware, ma non di entrambi, non abbia vantaggi non trascurabili nel prevedere i bit
generati dal pool di entropia.
Le implementazioni di Keymaster che tentano di stimare l'entropia nel pool interno presuppongono che i dati forniti daaddRngEntropy
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 di crittografia, specificando le autorizzazioni associate, associate in modo permanente alla chiave. Le implementazioni di Keymaster rendono impossibile utilizzare una chiave in modo incoerente con le autorizzazioni specificate al momento della generazione. Per quanto riguarda le autorizzazioni che l'hardware sicuro non può applicare, l'obbligo dell'hardware sicuro è limitato a garantire che le autorizzazioni non applicabili associate alla chiave non possano essere modificate, in modo che ogni chiamata a getKeyCharacteristics restituisca il valore originale. Inoltre, le caratteristiche restituite da
generateKey
assegnano correttamente le autorizzazioni tra gli
elenchi applicati tramite hardware e software. Per ulteriori dettagli, consulta
getKeyCharacteristics.
I parametri forniti a generateKey
dipendono dal tipo di chiave
generata. Questa sezione riassume i tag necessari e facoltativi per ciascun tipo di chiave. Per specificare il tipo è sempre necessaria
l'opzione Tag::ALGORITMO.
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 delle chiavi 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 i valori primi fino a 2^64.
I seguenti parametri non sono necessari per generare una chiave RSA, ma la creazione di una chiave RSA senza questi parametri genera una chiave inutilizzabile. Tuttavia, la funzione generateKey
non restituisce un errore se questi parametri vengono omessi.
- Tag::PURPOSE 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 di 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 può essere usata con gli altri digest, ma la digestione viene eseguita nel software. L'hardware viene chiamato per eseguire l'operazione con
Digest::NONE
. - Tag::PADDING specifica le modalità di spaziatura interna che possono essere utilizzate con la nuova chiave. Le implementazioni
che non supportano tutti gli algoritmi di digest devono inserire
PaddingMode::RSA_PSS
ePaddingMode::RSA_OAEP
nell'elenco delle caratteristiche chiave imposto dal software se sono specificati algoritmi di digest non supportati.
Chiavi ECDSA
Per generare una chiave ECDSA è necessario solo Tag::KEY_SIZE. È 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 è obbligatorio per la generazione.
Chiavi AES
Per generare una chiave AES è necessario solo Tag::KEY_SIZE. Se omesso, il metodo restituisce ErrorCode::UNSUPPORTED_KEY_SIZE
. I valori supportati sono 128 e 256, con il supporto facoltativo per le chiavi AES a 192 bit.
I seguenti parametri sono particolarmente pertinenti per le chiavi AES, ma non 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 spaziatura interna che possono essere utilizzate. Questo vale solo per le modalità ECB e CBC.
Se viene specificata la modalità di blocco GCM, fornisci
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 obbligatori per la generazione della chiave HMAC:
- Tag::KEY_SIZE specifica le dimensioni della chiave in bit. I valori inferiori a 64 e i valori non multipli di 8 non sono supportati. Sono supportati tutti i molteplici di 8, da 64 a 512. Potrebbero essere supportati valori più elevati.
- Tag::MIN_MAC_LENGTH specifica la lunghezza minima degli MAC che possono essere generati o verificati con questa chiave. Il valore è un multiplo di 8 e almeno 64.
- Tag::DIGEST
specifica l'algoritmo di digest per la chiave. È specificato esattamente un digest, altrimenti viene restituito
ErrorCode::UNSUPPORTED_DIGEST
. Se il digest non è supportato dal trustlet, restituisciErrorCode::UNSUPPORTED_DIGEST
.
Caratteristiche principali
Se l'argomento characteristics non è NULL, generateKey
restituisce le caratteristiche della chiave appena generata suddivise in modo appropriato in elenchi con applicazione hardware e software. Consulta
getKeyCharacteristics per una descrizione
delle caratteristiche da inserire in un determinato elenco. Le caratteristiche restituite includono tutti i parametri specificati per la generazione delle chiavi, 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 della chiave restituito. Tuttavia, sono vincolati crittograficamente al blob della chiave, in modo che se non vengono forniti i valori corretti quando viene utilizzata la chiave, l'utilizzo non va a buon fine. Analogamente,
Tag::ROOT_OF_TRUST è
legato in modo crittografico alla chiave, ma non può 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,
Resistenza al rollback
La resistenza al rollback significa che, una volta eliminata una chiave con deleteKey o deleteAllKeys, l'hardware sicuro non potrà più riutilizzarlo. Le implementazioni senza resistenza al rollback in genere restituisce il materiale della chiave generato o importato al chiamante come blob della chiave, un modulo criptato e autenticato. Quando l'archivio chiavi elimina il blob della chiave, la chiave non è più disponibile, ma un utente malintenzionato che in precedenza è riuscito a recuperare il materiale della chiave potrebbe potenzialmente ripristinarlo sul dispositivo.
Una chiave è resistente al rollback se l'hardware sicuro garantisce che le chiavi eliminate non possano essere ripristinate in un secondo momento. In genere, questo viene fatto memorizzando metadati aggiuntivi della chiave in una posizione attendibile che non può essere manipolata da un malintenzionato. Sui dispositivi mobili, il meccanismo utilizzato per questo è in genere RPMB (Replay Protected Memory Blocks). Poiché il numero di chiavi che possono essere create è essenzialmente illimitato e lo spazio di archiviazione attendibile utilizzato per la resistenza al rollback potrebbe essere limitato in termini di dimensioni, questo metodo deve riuscire anche se non è possibile fornire la resistenza al rollback per la nuova chiave. In questo caso, Tag::ROLLBACK_RESISTANT non deve essere aggiunto alle caratteristiche principali.
getKeyCharacteristics
Versione: 1, 2, 3
Questa funzione è stata introdotta in Keymaster 1 come
get_key_characteristics
e rinominata in Keymaster 3.
Restituisce i parametri e le autorizzazioni associati alla chiave fornita, suddivisi in due insiemi: applicati tramite hardware e applicati tramite software. Questa descrizione si applica anche agli elenchi di 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 stabilire se un determinato tag può rientrare nell'elenco applicato da hardware o software è che, se il significato del tag è completamente garantito da hardware protetto, questo viene applicato in modo forzato dall'hardware. Altrimenti, viene applicata in modo forzato dal software. Di seguito è riportato un elenco di tag specifici la cui allocazione corretta 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 sono nell'elenco con applicazione forzata hardware.
- I valori Tag::DIGEST supportati dall'hardware sicuro vengono inseriti nell'elenco dei dispositivi supportati dall'hardware. Le sintesi non supportate vengono inserite nell'elenco dei software supportati.
- I valori Tag::PADDING vengono generalmente inseriti nell'elenco supportato dall'hardware, a meno che non esista la possibilità che il software debba eseguire una modalità di spaziatura interna specifica. In questo caso, vengono inserite nell'elenco applicato dal software. Questa possibilità si verifica per le chiavi RSA che consentono il padding PSS o OAEP con algoritmi di digest che non sono supportati dall'hardware sicuro.
- Tag::USER_SECURE_ID e Tag::USER_AUTH_TYPE vengono applicati tramite hardware solo se l'autenticazione utente viene applicata tramite hardware. Per ottenere questo risultato, il trustlet Keymaster e il trustlet di autenticazione pertinente devono essere entrambi sicuri e condividere una chiave HMAC segreta utilizzata per firmare e convalidare i token di autenticazione. Per informazioni dettagliate, consulta la pagina Autenticazione.
- I tag Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME 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 tramite software.
- Tag::ORIGIN è sempre presente nell'elenco dell'hardware per le chiavi legate all'hardware. La sua presenza in questo elenco è il modo in cui i livelli superiori determinano che una chiave è basata su hardware.
importKey
Versione: 1, 2, 3
Questa funzione è stata introdotta in Keymaster 1 con il nome import_key
e rinominata in Keymaster 3.
Importa il materiale della chiave nell'hardware Keymaster. I parametri di definizione delle chiavi 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 specificato,
il trustlet deduce i valori dal materiale della chiave fornito e aggiunge
tag e valori appropriati alle caratteristiche chiave. Se i parametri vengono forniti, il trustlet li convalida in base al materiale della chiave. In caso di
mancata corrispondenza, il metodo restituisce
ErrorCode::IMPORT_PARAMETER_MISMATCH
. - Tag::ORIGIN restituito ha lo stesso valore di
KeyOrigin::IMPORTED
.
EsportazioneChiave
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 RSA o EC Keymaster.
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
. Analogamente, 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 e viene implementato solo dai moduli Keymaster che offrono resistenza al rollback.
deleteAllKeys
Versione: 1, 2, 3
Questa funzione è stata introdotta in Keymaster 1 con il nome delete_all_keys
e rinominata in Keymaster 3.
Consente di eliminare tutte le chiavi. Questo metodo è facoltativo e viene implementato solo dai moduli Keymaster che offrono resistenza al rollback.
destroyAttestationIds
Versione: 3
Il metodo destroyAttestationIds()
viene utilizzato per disattivare definitivamente la nuova funzionalità (facoltativa, ma vivamente consigliata) di attestazione dell'identità. Se il TEE non ha modo di garantire che l'attestazione dell'identità venga disattivata definitivamente dopo l'uso di questo metodo, l'attestazione dell'identità non deve essere implementata affatto, nel qual caso questo metodo non fa nulla e restituisce ErrorCode::UNIMPLEMENTED
. Se la verifica dell'identità è supportata, questo metodo deve essere implementato e deve disattivare definitivamente tutti i futuri tentativi di verifica dell'identità. Il metodo può essere chiamato un numero qualsiasi di volte. Se l'attestazione dell'identità è già disattivata definitivamente, il metodo non fa nulla e restituisce ErrorCode::OK
.
Gli unici codici di errore che questo metodo può restituire sono
ErrorCode::UNIMPLEMENTED
(se l'attestazione dell'identità non è supportata),
ErrorCode:OK
, ErrorCode::KEYMASTER_NOT_CONFIGURED
o
uno dei codici di errore che indicano un errore di comunicazione con l'hardware sicuro.
inizia
Versione: 1, 2, 3
Avvia un'operazione di crittografia utilizzando la chiave specificata, per lo scopo specificato, con i parametri specificati (se appropriato) e restituisce un handle dell'operazione utilizzato con update e finish per completare l'operazione. L'handle dell'operazione viene utilizzato anche come token "challenge" nelle operazioni autenticate e, per queste operazioni, è incluso nel campo challenge
del token di autenticazione.
Un'implementazione di Keymaster supporta almeno 16 operazioni contemporaneamente. L'archivio chiavi ne utilizza fino a 15, lasciandone uno per vold utilizzabile per la crittografia delle password. Quando l'archivio chiavi ha 15 operazioni in corso (begin
è stata chiamata, ma non sono stati
chiamati finish
o abort
) e riceve una richiesta di inizio di un 16, chiama
abort
sull'operazione utilizzata meno di recente per ridurre il numero di
operazioni attive a 14 prima di chiamare begin
per 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 a begin
includono quei
tag con i valori originariamente specificati nell'argomento inParams
per questo metodo.
Applicazione delle autorizzazioni
Durante questo metodo, le seguenti autorizzazioni chiave vengono applicate dal trustlet se l'implementazione le ha inserite nelle caratteristiche "applicata dall'hardware" e se l'operazione non è un'operazione di chiave pubblica. Le operazioni con chiavi pubbliche, ovvero KeyPurpose::ENCRYPT
e KeyPurpose::VERIFY
, con chiavi RSA o EC, possono essere completate 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 delle chiavi, a meno che l'operazione richiesta non sia un'operazione con chiave pubblica. Se lo scopo specificato non corrisponde e l'operazione non è un'operazione con chiave pubblica,begin
restituisceErrorCode::UNSUPPORTED_PURPOSE
. Le operazioni con chiavi pubbliche sono operazioni di crittografia o verifica asimmetrica. - Tag::ACTIVE_DATETIME può essere applicato in modo forzato solo se è disponibile un'origine ora UTC attendibile. Se la data e l'ora correnti precedono il valore del tag, il metodo restituisce
ErrorCode::KEY_NOT_YET_VALID
. - Tag::ORIGINATION_EXPIRE_DATETIME
può essere applicato solo se è disponibile un'origine ora UTC attendibile. Se la data e l'ora correnti sono successive al valore del tag e lo scopo è
KeyPurpose::ENCRYPT
oKeyPurpose::SIGN
, il metodo restituisceErrorCode::KEY_EXPIRED
. - Tag::USAGE_EXPIRE_DATETIME
può essere applicato solo se è disponibile un'origine ora UTC attendibile. Se la data e l'ora correnti sono successive al valore del tag e lo scopo è
KeyPurpose::DECRYPT
oKeyPurpose::VERIFY
, il metodo restituisceErrorCode::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
. Per informazioni dettagliate sull'implementazione, consulta la descrizione del tag. - Tag::MAX_USES_PER_BOOT
viene confrontato con un contatore sicuro che monitora gli utilizzi 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 applicato da questo metodo solo se la chiave contiene anche
Tag::AUTH_TIMEOUT.
Se la chiave contiene entrambi, questo metodo deve ricevere un valore valido per Tag::AUTH_TOKEN in
inParams
. Affinché il token di autenticazione sia valido, tutte le seguenti condizioni devono essere vere:- Il campo HMAC viene convalidato correttamente.
- Almeno uno dei valori di Tag::USER_SECURE_ID della chiave corrisponde ad almeno uno dei valori dell'ID sicuro nel token.
- La chiave ha un valore Tag::USER_AUTH_TYPE che corrisponde al tipo di autenticazione nel token.
Se una di queste condizioni non è 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 chi chiama 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 solo bootloader al termine dell'esecuzione del bootloader, restituisce
ErrorCode::INVALID_KEY_BLOB
.
Chiavi RSA
Tutte le operazioni con le chiavi 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 modalità di riempimento OAEP. In questi casi, l'autore della chiamata specifica esattamente un digest in inParams
. Se non specificato o specificato più di una volta, il metodo restituisce ErrorCode::UNSUPPORTED_DIGEST
.
Le operazioni con chiavi private (KeyPurpose::DECYPT
e KeyPurpose::SIGN
)
richiedono l'autorizzazione di digest e padding, il che significa che le autorizzazioni delle chiavi
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 chiavi pubbliche
(KeyPurpose::ENCRYPT
e KeyPurpose::VERIFY
) sono consentite con
digest o padding non autorizzati.
Ad eccezione di PaddingMode::NONE
, tutte le modalità di spaziatura interna RSA sono
applicabili solo a determinati scopi. Nello specifico,
PaddingMode::RSA_PKCS1_1_5_SIGN
e PaddingMode::RSA_PSS
supportano solo firma e verifica, mentre PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT
e PaddingMode::RSA_OAEP
supportano solo la crittografia e la decriptazione.
Il metodo restituisce ErrorCode::UNSUPPORTED_PADDING_MODE
se la modalità specificata non supporta lo scopo specificato.
Esistono alcune interazioni importanti tra le modalità di spaziatura interna e le sintesi:
PaddingMode::NONE
indica che viene eseguita un'operazione RSA "non elaborata". Se la firma o la verifica è attiva, per il digest viene specificatoDigest::NONE
. Per la crittografia o la decrittografia senza padding non è necessario alcun digest.- La spaziatura interna
PaddingMode::RSA_PKCS1_1_5_SIGN
richiede un digest. Il digest può essereDigest::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. L'implementazione invece genera0x00 || 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 più grande del messaggio, altrimenti il metodo restituisceErrorCode::INVALID_INPUT_LENGTH
. - Il padding
PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT
non richiede un digest. - Il padding
PaddingMode::RSA_PSS
richiede un digest, che non può essereDigest::NONE
. SeDigest::NONE
è specificato, il metodo restituisceErrorCode::INCOMPATIBLE_DIGEST
. Inoltre, le dimensioni della chiave RSA devono essere almeno 2 + D byte più grandi delle dimensioni in output del digest, dove D è la dimensione del digest in byte. In caso contrario, il metodo restituisceErrorCode::INCOMPATIBLE_DIGEST
. La dimensione del sale è D. - Il padding
PaddingMode::RSA_OAEP
richiede un digest, che non può essereDigest::NONE
. SeDigest::NONE
è specificato, il metodo restituisceErrorCode::INCOMPATIBLE_DIGEST
.
Chiavi EC
Le operazioni con chiavi EC specificano esattamente una modalità di spaziatura interna in inParams
.
Se non specificato o specificato più di una volta, il metodo
restituisce ErrorCode::UNSUPPORTED_PADDING_MODE
.
Le operazioni con chiavi private (KeyPurpose::SIGN
) richiedono l'autorizzazione di digest e padding, il che significa che le autorizzazioni delle chiavi devono contenere i valori specificati. In caso contrario, restituisce
ErrorCode::INCOMPATIBLE_DIGEST
. Le operazioni con chiavi pubbliche
(KeyPurpose::VERIFY
) sono consentite con digest o padding non autorizzati.
Chiavi AES
Le operazioni con le chiavi AES specificano esattamente una modalità di blocco e una modalità di riempimento
in inParams
. Se uno dei due valori non è specificato o viene specificato più di una volta, restituisce 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à di blocco è BlockMode::GCM
, inParams
specifica Tag::MAC_LENGTH
e il
valore specificato è un multiplo di 8 non superiore a 128
o inferiore al valore di Tag::MIN_MAC_LENGTH
nelle
autorizzazioni della chiave. Per lunghezze MAC maggiori di 128 o non multipli di
8, restituisci ErrorCode::UNSUPPORTED_MAC_LENGTH
. Per i valori inferiori alla lunghezza minima della chiave, restituisci ErrorCode::INVALID_MAC_LENGTH
.
Se la modalità di blocco è BlockMode::GCM
o BlockMode::CTR
,
la modalità di spaziatura interna specificata deve essere PaddingMode::NONE
.
Per BlockMode::ECB
o BlockMode::CBC
, la modalità può essere
PaddingMode::NONE
o PaddingMode::PKCS7
. Se la modalità di spaziatura interna
non soddisfa queste condizioni, restituisci ErrorCode::INCOMPATIBLE_PADDING_MODE
.
Se la modalità di blocco è BlockMode::CBC
, BlockMode::CTR
o BlockMode::GCM
, è necessario un vettore di inizializzazione o un nonce.
Nella maggior parte dei casi, gli utenti che chiamano non devono fornire un IV o un nonce. In questo caso, l'implementazione Keymaster genera un IV o un nonce casuale e li restituisce con
Tag::NONCE in outParams
.
Gli IV CBC e CTR sono 16 byte. I nonce GCM sono di 12 byte. Se le autorizzazioni della chiave contengono Tag::CALLER_NONCE, il chiamante può fornire un IV o un nonce con Tag::NONCE in inParams
. Se viene fornito un nonce quando
Tag::CALLER_NONCE
non è autorizzato, restituisci ErrorCode::CALLER_NONCE_PROHIBITED
.
Se non viene fornito un nonce quando
Tag::CALLER_NONCE
è autorizzato, genera un IV/nonce casuale.
Chiavi HMAC
Le operazioni relative alle chiavi HMAC specificano Tag::MAC_LENGTH
in inParams
.
Il valore specificato deve essere un multiplo di 8 non superiore alla lunghezza del digest o inferiore al valore di Tag::MIN_MAC_LENGTH
nelle autorizzazioni delle chiavi. Per lunghezze MAC maggiori della lunghezza del digest o non multiple di 8, restituisce ErrorCode::UNSUPPORTED_MAC_LENGTH
.
Per i valori inferiori alla lunghezza minima della chiave, restituisce
ErrorCode::INVALID_MAC_LENGTH
.
update
Versione: 1, 2, 3
Fornisce i dati da elaborare in un'operazione in corso avviata con begin.
L'operazione è specificata dal parametro operationHandle
.
Per offrire maggiore flessibilità nella gestione del buffer, le implementazioni di questo metodo hanno la possibilità di consumare meno dati di quelli forniti. Il chiamante è responsabile del ciclo per fornire 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 altri. Se vengono forniti più di zero byte e vengono consumati zero byte, i chiamanti lo considerano un errore e interrompono l'operazione.
Le implementazioni possono anche scegliere la quantità di dati da restituire, in seguito all'aggiornamento. Questo è rilevante solo per le operazioni di crittografia e decrittografia, perché la firma e la verifica non restituiscono dati fino a finish. Restituire i dati il prima possibile, anziché metterli in un 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
futuro utilizzo dell'handle, con questo metodo,
finish o abort,
restituisce ErrorCode::INVALID_OPERATION_HANDLE
.
Applicazione delle autorizzazioni
L'applicazione forzata dell'autorizzazione delle chiavi viene eseguita principalmente in begin. L'unica eccezione è il caso in cui la chiave abbia:
- Uno o più Tag::USER_SECURE_IDs e
- Non ha un valore Tag::AUTH_TIMEOUT
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 valore Tag::USER_AUTH_TYPE della chiave e contenga l'handle dell'operazione corrente nel campo della verifica. Se queste condizioni non sono soddisfatte, restituisce
ErrorCode::KEY_USER_NOT_AUTHENTICATED
.
L'utente chiamante fornisce il token di autenticazione a ogni chiamata a update e finish. L'implementazione deve convalidare il token una sola volta, se 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. Non può consumare solo una parte del blocco. Tuttavia, se il chiamante sceglie di fornire i dati in più aggiornamenti, questo metodo li 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), restituisci 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 non può consumare solo una parte del blocco.
Tuttavia, se chi chiama sceglie di fornire i dati in più aggiornamenti, questo metodo li accetta. Se l'utente che chiama fornisce più dati da firmare di quelli che possono essere utilizzati, i dati vengono troncati in modo silenzioso. Questo è diverso 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 criptare o decriptare. Una chiamata di aggiornamento può ricevere sia i dati associati sia i dati da criptare/decriptare, ma gli aggiornamenti successivi non possono includere i dati associati. Se chi chiama fornisce i dati associati a una chiamata di aggiornamento dopo una chiamata
che include dati da criptare/decriptare, restituisci ErrorCode::INVALID_TAG
.
Per la crittografia GCM, il tag viene aggiunto al testo cifrato da
finish. Durante la decrittografia, gli ultimi Tag::MAC_LENGTH
byte dei dati forniti all'ultima chiamata di aggiornamento sono il tag. Poiché una determinata chiamata ad update non può sapere se si tratta dell'ultima chiamata, elabora tutti i dati tranne la lunghezza del tag e memorizza i possibili dati del tag al fine.
fine
Versione: 1, 2, 3
Completa un'operazione in corso avviata con begin, elaborando tutti i dati non ancora elaborati forniti dagli update.
Questo metodo è l'ultimo chiamato in un'operazione, quindi vengono restituiti tutti i dati elaborati.
Indipendentemente dal fatto che l'operazione venga completata correttamente o restituisca un errore, questo metodo completa
l'operazione e quindi invalida l'handle dell'operazione fornito. Qualsiasi utilizzo futuro dell'handle, con questo metodo oppure con update o abort, restituisce ErrorCode::INVALID_OPERATION_HANDLE
.
Le operazioni di firma restituiscono la firma come output. Le operazioni di verifica accettano la firma nel parametro signature
e non restituiscono alcun output.
Applicazione dell'autorizzazione
L'applicazione dell'autorizzazione delle chiavi viene eseguita principalmente in begin. L'unica eccezione è il caso in cui la chiave abbia:
- Uno o più Tag::USER_SECURE_IDs e
- Non ha un Tag::AUTH_TIMEOUT
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 contiene l'handle dell'operazione corrente nel campo della verifica. Se queste condizioni non sono soddisfatte, restituisci
ErrorCode::KEY_USER_NOT_AUTHENTICATED
.
L'utente che chiama fornisce il token di autenticazione a ogni chiamata a update e finish. L'implementazione deve convalidare il token una sola volta, se preferisce.
Chiavi RSA
Di seguito sono riportati alcuni requisiti aggiuntivi, a seconda della modalità di spaziatura interna:
PaddingMode::NONE
. Per le operazioni di firma e crittografia senza padding, se i dati forniti sono più brevi della chiave, i dati devono essere sottoposti a zero padding a sinistra prima della firma/crittografia. Se i dati hanno la stessa lunghezza della chiave, ma sono numericamente maggiori, restituisciErrorCode::INVALID_ARGUMENT
. Per le operazioni di verifica e decriptazione, i dati devono essere lunghi esattamente quanto la chiave. In caso contrario, restituisciErrorCode::INVALID_INPUT_LENGTH.
PaddingMode::RSA_PSS
. Per le operazioni di firma con padding PSS, il sale PSS è la dimensione del digest del messaggio e viene generato in modo casuale. Il digest specificato con Tag::DIGEST ininputParams
in begin viene utilizzato come algoritmo di digest PSS e come algoritmo di digest MGF1.PaddingMode::RSA_OAEP
. Il digest specificato con Tag::DIGEST ininputParams
in begin viene utilizzato come algoritmo digest OAEP e SHA1 viene utilizzato come algoritmo digest MGF1.
Chiavi ECDSA
Se i dati forniti per la firma o la verifica senza padding sono troppo lunghi, troncali.
Chiavi AES
Alcune condizioni aggiuntive, a seconda della modalità di blocco:
BlockMode::ECB
oBlockMode::CBC
. Se la spaziatura interna èPaddingMode::NONE
e la lunghezza dei dati non è un multiplo della dimensione del blocco AES, restituisceErrorCode::INVALID_INPUT_LENGTH
. Se la spaziatura interna èPaddingMode::PKCS7
, inserisci i dati in base alla specifica PKCS#7. Tieni presente che PKCS#7 consiglia di aggiungere un blocco di riempimento aggiuntivo se i dati sono un multiplo della lunghezza del blocco.BlockMode::GCM
. Durante la crittografia, dopo aver elaborato tutto il testo non criptato, calcola il tag (Tag::MAC_LENGTH byte) e aggiungilo al testo cifrato restituito. Durante la decriptazione, elabora gli ultimi Tag::MAC_LENGTH byte come tag. Se la verifica del tag non va a buon fine, restituisceErrorCode::VERIFICATION_FAILED
.
interrompi
Versione: 1, 2, 3
Interrompe l'operazione in corso. Dopo la chiamata ad abort, restituisce
ErrorCode::INVALID_OPERATION_HANDLE
per qualunque uso successivo dell'handle dell'operazione fornito con update,
finish o abort.
algoritmi_supportati
Versione: 1
Restituisce l'elenco degli algoritmi supportati dall'implementazione hardware di Keymaster. Un'implementazione software restituisce un elenco vuoto, mentre un'implementazione ibrida restituisce un elenco contenente solo gli algoritmi supportati dall'hardware.
Le implementazioni di Keymaster 1 supportano RSA, EC, AES e HMAC.
get_supported_block_modes
Versione: 1
Restituisce l'elenco delle modalità di blocco AES supportate dall'implementazione hardware di Keymaster per un algoritmo e uno scopo specificati.
Per RSA, EC e HMAC, che non sono crittografie a blocchi, il metodo restituisce un elenco vuoto per tutti gli scopi validi. Per motivi non validi, il metodo dovrebbe
restituire ErrorCode::INVALID_PURPOSE
.
Le implementazioni di Keymaster 1 supportano ECB, CBC, CTR e GCM per la crittografia e la decrittografia AES.
modalità_porto_spaziatura_supportata
Versione: 1
Restituisce l'elenco delle modalità di riempimento supportate dall'implementazione hardware di Keymaster per un algoritmo e uno scopo specificati.
HMAC ed EC non hanno nozione di padding, pertanto il metodo restituisce un elenco vuoto per tutti gli scopi validi. Scopi non validi dovrebbero causare il ritorno del metodo
ErrorCode::INVALID_PURPOSE
.
Per RSA, le implementazioni di Keymaster 1 supportano:
- Crittografia, decrittografia, firma e verifica non con spaziatura aggiuntiva. Per la crittografia e la firma non riempite, se il messaggio è più breve del modulo pubblico, le implementazioni devono contenere degli zeri. Per la decriptazione e la verifica senza padding, la lunghezza dell'input deve corrispondere alle dimensioni del modulo pubblico.
- Modalità di crittografia e spaziatura interna della firma PKCS#1 v1.5
- PSS con una lunghezza minima del sale di 20 caratteri
- OAEP
Per AES nelle modalità ECB e CBC, le implementazioni di Keymaster 1 supportano il padding zero e il padding PKCS#7. Le modalità CTR e GCM non supportano solo la spaziatura interna.
get_supported_digests
Versione: 1
Restituisce l'elenco delle modalità digest supportate dall'implementazione hardware Keymaster per uno scopo e un algoritmo specifici.
Nessuna modalità AES supporta o richiede l'utilizzo di digest, pertanto il metodo restituisce un elenco vuoto per scopi validi.
Le implementazioni Keymaster 1 possono implementare un sottoinsieme dei digest definiti. Le implementazioni forniscono SHA-256 e possono fornire MD5, SHA1, SHA-224, SHA-256, SHA384 e SHA512 (l'insieme completo di digest definiti).
get_supported_import_formats
Versione: 1
Restituisce l'elenco dei formati di importazione supportati dall'implementazione hardware Keymaster di un algoritmo specificato.
Le implementazioni di Keymaster 1 supportano il formato PKCS#8 (senza protezione tramite password) per l'importazione di coppie di chiavi RSA ed EC e supportano l'importazione RAW del materiale della chiave AES e HMAC.
get_supported_export_formats
Versione: 1
Restituisce l'elenco dei formati di esportazione supportati dall'implementazione hardware Keymaster di un algoritmo specificato.
Le implementazioni di Keymaster1 supportano il formato X.509 per l'esportazione delle chiavi pubbliche RSA e EC. L'esportazione di chiavi private o asimmetriche non è supportata.
Funzioni storiche
Keymaster 0
Le seguenti funzioni appartengono alla definizione originale di Keymaster 0. Erano presenti nella struct keymaster1_device_t di Keymaster 1. Tuttavia, in Keymaster 1.0 non sono stati implementati e i relativi puntatori di funzione sono stati impostati su NULL.
generate_keypair
import_keypair
get_keypair_public
delete_keypair
delete_all
sign_data
Verify_data
Keymaster 1
Le seguenti funzioni appartengono alla definizione di Keymaster 1, ma sono state rimosse in Keymaster 2, insieme alle funzioni di Keymaster 0 elencate sopra.
get_supported_algorithms
get_supported_block_modes
get_supported_padding_modes
get_supported_digests
get_supported_import_formats
get_supported_export_formats
Keymaster 2
Le seguenti funzioni appartengono alla definizione di Keymaster 2, ma sono state rimosse in Keymaster 3, insieme alle funzioni di Keymaster 1 elencate sopra.
configure