Chiave e Attestazione ID

Keystore fornisce un luogo più sicuro per creare, archiviare e utilizzare le chiavi crittografiche in modo controllato. Quando l'archiviazione delle chiavi basata su hardware è disponibile e utilizzata, il materiale della chiave è più sicuro contro l'estrazione dal dispositivo e Keymaster applica restrizioni difficili da sovvertire.

Ciò è vero, tuttavia, solo se è noto che le chiavi dell'archivio chiavi si trovano nell'archiviazione supportata dall'hardware. In Keymaster 1, non c'era modo per le app o i server remoti di verificare in modo affidabile se fosse così. Il demone keystore ha caricato l'HAL keymaster disponibile e ha creduto a qualunque cosa l'HAL dicesse rispetto al supporto hardware delle chiavi.

Per rimediare a questo, Keymaster ha introdottol'attestazione della chiave in Android 7.0 (Keymaster 2) e l'attestazione dell'ID in Android 8.0 (Keymaster 3).

L'attestazione della chiave mira a fornire un modo per determinare con certezza se una coppia di chiavi asimmetriche è supportata dall'hardware, quali sono le proprietà della chiave e quali vincoli vengono applicati al suo utilizzo.

L'attestazione dell'ID consente al dispositivo di fornire una prova dei propri identificatori hardware, come il numero di serie o l'IMEI.

Attestazione chiave

Per supportare l'attestazione della chiave, Android 7.1 ha introdotto un set di tag, tipo e metodo nell'HAL.

Tag

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Tipo

Keymaster 2 e versioni precedenti

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

Metodo AttestKey

Maestro delle chiavi 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 e versioni precedenti

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev è la struttura del dispositivo keymaster.
  • keyToAttest è il BLOB di chiavi restituito da generateKey per il quale verrà creata l'attestazione.
  • attestParams è un elenco di tutti i parametri necessari per l'attestazione. Questo include Tag::ATTESTATION_CHALLENGE ed eventualmente Tag::RESET_SINCE_ID_ROTATION , così come Tag::APPLICATION_ID e Tag::APPLICATION_DATA . Gli ultimi due sono necessari per decrittografare il BLOB di chiavi se sono stati specificati durante la generazione della chiave.
  • certChain è il parametro di output, che restituisce un array di certificati. La voce 0 è il certificato di attestazione, ovvero certifica la chiave da keyToAttest e contiene l'estensione dell'attestazione.

Il metodo attestKey è considerato un'operazione di chiave pubblica sulla chiave attestata, perché può essere chiamato in qualsiasi momento e non deve soddisfare vincoli di autorizzazione. Ad esempio, se la chiave attestata richiede l'autenticazione dell'utente per l'utilizzo, è possibile generare un'attestazione senza l'autenticazione dell'utente.

Certificato di attestazione

Il certificato di attestazione è un certificato X.509 standard, con un'estensione di attestazione facoltativa che contiene una descrizione della chiave attestata. Il certificato è firmato con una chiave di attestazione certificata. La chiave di attestazione può utilizzare un algoritmo diverso rispetto alla chiave da attestare.

Il certificato di attestazione contiene i campi nella tabella seguente e non può contenere campi aggiuntivi. Alcuni campi specificano un valore di campo fisso. I test CTS convalidano che il contenuto del certificato è esattamente come definito.

SEQUENZA certificato

Nome del campo (vedi RFC 5280 ) Valore
tbsCertificate Certificato TBS SEQUENCE
signatureAlgorithm AlgorithmIdentifier dell'algoritmo utilizzato per firmare la chiave:
ECDSA per chiavi EC, RSA per chiavi RSA.
firmaValore STRINGA DI BIT, firma calcolata su tbsCertificate con codifica DER ASN.1.

Certificato TBS SEQUENCE

Nome del campo (vedi RFC 5280 ) Valore
version INTEGER 2 (indica certificato v3)
serialNumber INTEGER 1 (valore fisso: uguale su tutti i certificati)
signature AlgorithmIdentifier dell'algoritmo utilizzato per firmare la chiave: ECDSA per le chiavi EC, RSA per le chiavi RSA.
issuer Uguale al campo oggetto della chiave di attestazione batch.
validity SEQUENCE di due date, contenente i valori di Tag::ACTIVE_DATETIME e Tag::USAGE_EXPIRE_DATETIME . Questi valori sono espressi in millisecondi dal 1 gennaio 1970. Vedere RFC 5280 per le rappresentazioni corrette della data nei certificati.
Se Tag::ACTIVE_DATETIME non è presente, utilizza il valore di Tag::CREATION_DATETIME . Se Tag::USAGE_EXPIRE_DATETIME non è presente, utilizzare la data di scadenza del certificato della chiave di attestazione batch.
subject CN = "Android Keystore Key" (valore fisso: uguale su tutti i certificati)
subjectPublicKeyInfo SubjectPublicKeyInfo contenente la chiave pubblica attestata.
extensions/Key Usage digitalSignature: imposta se la chiave ha uno scopo KeyPurpose::SIGN o KeyPurpose::VERIFY . Tutti gli altri bit non impostati.
extensions/CRL Distribution Points Valore da definire
extensions/"attestation" L'OID è 1.3.6.1.4.1.11129.2.1.17; il contenuto è definito nella sezione Estensione attestazione di seguito. Come per tutte le estensioni di certificato X.509, il contenuto è rappresentato come OCTET_STRING contenente una codifica DER dell'attestazione SEQUENCE.

Estensione attestazione

L'estensione attestation contiene una descrizione completa delle autorizzazioni del keymaster associate alla chiave, in una struttura che corrisponde direttamente agli elenchi di autorizzazioni utilizzati in Android e nel keymaster HAL. Ogni tag in un elenco di autorizzazioni è rappresentato da una voce ASN.1 SEQUENCE , contrassegnata esplicitamente con il numero di tag keymaster, ma con il descrittore del tipo (quattro bit di ordine elevato) mascherato.

Ad esempio, in Keymaster 3, Tag::PURPOSE è definito in types.hal come ENUM_REP | 1 . Per l'estensione dell'attestazione, il valore ENUM_REP viene rimosso, lasciando il tag 1 . (Per Keymaster 2 e precedenti, KM_TAG_PURPOSE è definito in keymaster_defs.h.)

I valori vengono tradotti in modo semplice nei tipi ASN.1, secondo questa tabella:

Tipo di maestro di chiavi Tipo ASN.1
ENUM NUMERO INTERO
ENUM_REP INSIEME di INTERI
UINT NUMERO INTERO
UINT_REP INSIEME di INTERI
ULONG NUMERO INTERO
ULONG_REP INSIEME di INTERI
DATE INTEGER (millisecondi dal 1 gennaio 1970 00:00:00 GMT)
BOOL NULL (in keymaster, tag presente significa vero, assente significa falso.
La stessa semantica si applica alla codifica ASN.1)
BIGNUM Attualmente non utilizzato, quindi non è definita alcuna mappatura
BYTES OCTET_STRING

Schema

Il contenuto dell'estensione dell'attestazione è descritto dal seguente schema ASN.1.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

Campi KeyDescription

I campi keymasterVersion e attestationChallenge sono identificati in modo posizionale, anziché in base al tag, quindi i tag nella forma codificata specificano solo il tipo di campo. I campi rimanenti sono contrassegnati in modo implicito come specificato nello schema.

Nome del campo Tipo Valore
attestationVersion NUMERO INTERO Versione dello schema di attestazione: 1, 2 o 3.
attestationSecurity Livello di sicurezza Il livello di sicurezza di questa attestazione. È possibile ottenere attestati software di chiavi supportate da hardware. Tali attestazioni non possono essere attendibili se il sistema Android è compromesso.
keymasterVersion NUMERO INTERO Versione del dispositivo keymaster: 0, 1, 2, 3 o 4.
keymasterSecurity Livello di sicurezza Il livello di sicurezza dell'implementazione keymaster.
attestationChallenge OCTET_STRING Valore di Tag::ATTESTATION_CHALLENGE , specificato nella richiesta di attestazione.
uniqueId OCTET_STRING ID univoco facoltativo, presente se la chiave ha Tag::INCLUDE_UNIQUE_ID
softwareEnforced Elenco autorizzazioni Facoltativo, autorizzazioni keymaster che non sono applicate dal TEE, se presenti.
teeEnforced Elenco autorizzazioni Facoltativo, autorizzazioni Keymaster che vengono applicate dal TEE, se presenti.

Campi AuthorizationList

I campi AuthorizationList sono tutti facoltativi e sono identificati dal valore del tag keymaster, con i bit di tipo mascherati. Viene utilizzato il tagging esplicito in modo che i campi contengano anche un tag che indica il loro tipo ASN.1, per facilitare l'analisi.

Per i dettagli sui valori di ciascun campo, vedere types.hal per Keymaster 3 e keymaster_defs.h per Keymaster 2 e versioni successive. I nomi dei tag Keymaster sono stati trasformati in nomi di campo omettendo il prefisso KM_TAG e cambiando il resto in camel case, quindi Tag::KEY_SIZE è diventato keySize .

Campi RootOfTrust

I campi RootOfTrust sono identificati in modo posizionale.

Nome del campo Tipo Valore
verifiedBootKey OCTET_STRING Un hash sicuro della chiave usata per verificare l'immagine del sistema. SHA-256 consigliato.
deviceLocked BOOLEANO Vero se il bootloader è bloccato, il che significa che è possibile eseguire il flashing solo delle immagini firmate e che viene eseguito il controllo di avvio verificato.
verifiedBootState Stato di avvio verificato Stato di avvio verificato.
verifiedBootHash OCTET_STRING Un riepilogo di tutti i dati protetti da Verified Boot. Per i dispositivi che usano l'implementazione Android Verified Boot di Verified Boot, questo valore contiene il digest di VBMeta struct o la struttura dei metadati di Verified Boot. Per ulteriori informazioni su come calcolare questo valore, vedere The VBMeta Digest

Valori VerifiedBootState

I valori verifiedBootState hanno i seguenti significati:

Valore Senso
Verified Indica una catena di attendibilità completa che si estende dal bootloader alle partizioni verificate, inclusi il bootloader, la partizione di avvio e tutte le partizioni verificate.
In questo stato, il verifiedBootKey è l'hash del certificato incorporato, ovvero il certificato non modificabile masterizzato nella ROM.
Questo stato corrisponde allo stato di avvio verde come documentato nella documentazione del flusso di avvio verificato .
SelfSigned Indica che la partizione di avvio è stata verificata utilizzando il certificato incorporato e la firma è valida. Il bootloader visualizza un avviso e l'impronta digitale della chiave pubblica prima di consentire il proseguimento del processo di avvio.
In questo stato, il verifiedBootKey è l'hash del certificato autofirmato.
Questo stato corrisponde allo stato di avvio giallo come documentato nella documentazione del flusso di avvio verificato .
Unverified Indica che un dispositivo può essere liberamente modificato. L'integrità del dispositivo è lasciata all'utente per la verifica fuori banda. Il bootloader visualizza un avviso all'utente prima di consentire il proseguimento del processo di avvio.
In questo stato il verifiedBootKey è vuoto.
Questo stato corrisponde allo stato di avvio arancione come documentato nella documentazione del flusso di avvio verificato .
Failed Indica che il dispositivo non ha superato la verifica. Nessun certificato di attestazione contiene effettivamente questo valore, perché in questo stato il bootloader si arresta. È incluso qui per completezza.
Questo stato corrisponde allo stato di avvio rosso come documentato nella documentazione del flusso di avvio verificato .

Valori SecurityLevel

I valori di securityLevel hanno i seguenti significati:

Valore Senso
Software Il codice che crea o gestisce l'elemento rilevante (attestazione o chiave) è implementato nel sistema Android e potrebbe essere alterato se tale sistema viene compromesso.
TrustedEnvironment Il codice che crea o gestisce l'elemento rilevante (attestazione o chiave) è implementato in un Trusted Execution Environment (TEE). Potrebbe essere alterato se il TEE è compromesso, ma il TEE è altamente resistente alla compromissione remota e moderatamente resistente alla compromissione tramite attacco hardware diretto.
StrongBox Il codice che crea o gestisce l'elemento rilevante (attestato o chiave) è implementato in un modulo di sicurezza hardware dedicato. Potrebbe essere alterato se il modulo di sicurezza hardware viene compromesso, ma è altamente resistente alla compromissione remota e altamente resistente alla compromissione tramite attacco hardware diretto.

ID univoco

L'ID univoco è un valore a 128 bit che identifica il dispositivo, ma solo per un periodo di tempo limitato. Il valore è calcolato con:

HMAC_SHA256(T || C || R, HBK)

Dove:

  • T è il "valore del contatore temporale", calcolato dividendo il valore di Tag::CREATION_DATETIME per 2592000000, eliminando qualsiasi resto. T cambia ogni 30 giorni (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C è il valore di Tag::APPLICATION_ID
  • R è 1 se Tag::RESET_SINCE_ID_ROTATION è presente nel parametro attest_params della chiamata attest_key oppure 0 se il tag non è presente.
  • HBK è un segreto univoco legato all'hardware noto al Trusted Execution Environment e mai rivelato da esso. Il segreto contiene almeno 128 bit di entropia ed è unico per il singolo dispositivo (l'unicità probabilistica è accettabile dati i 128 bit di entropia). HBK dovrebbe essere derivato dal materiale della chiave fusa tramite HMAC o AES_CMAC.

Tronca l'output di HMAC_SHA256 a 128 bit.

Chiavi di attestazione e certificati

Due chiavi, una RSA e una ECDSA, e le corrispondenti catene di certificati, vengono fornite in modo sicuro nel dispositivo.

Android 12 introduce il Remote Key Provisioning e Android 13 richiede che i dispositivi lo implementino. Remote Key Provisioning fornisce ai dispositivi sul campo certificati di attestazione ECDSA P256 per applicazione. Questi certificati hanno una durata più breve rispetto ai certificati forniti in fabbrica.

Attestato di identità

Android 8.0 include il supporto facoltativo per l'attestazione dell'ID per i dispositivi con Keymaster 3. L'attestazione dell'ID consente al dispositivo di fornire una prova dei suoi identificatori hardware, come il numero di serie o l'IMEI. Sebbene sia una funzionalità opzionale, si consiglia vivamente che tutte le implementazioni di Keymaster 3 ne forniscano il supporto perché essere in grado di dimostrare l'identità del dispositivo consente a casi d'uso come la vera configurazione remota zero-touch di essere più sicuri (poiché il lato remoto può essere certo che sta parlando con il dispositivo giusto, non un dispositivo che falsifica la sua identità).

L'attestazione dell'ID funziona creando copie degli identificatori hardware del dispositivo a cui solo il TEE (Trusted Execution Environment) può accedere prima che il dispositivo lasci la fabbrica. Un utente può sbloccare il bootloader del dispositivo e modificare il software di sistema e gli identificatori riportati dai framework Android. Le copie degli identificatori conservate dal TEE non possono essere manipolate in questo modo, garantendo che l'attestazione dell'ID del dispositivo attesti solo e solo gli identificatori hardware originali del dispositivo, vanificando così i tentativi di spoofing.

La superficie API principale per l'attestazione dell'ID si basa sul meccanismo di attestazione della chiave esistente introdotto con Keymaster 2. Quando si richiede un certificato di attestazione per una chiave detenuta da keymaster, il chiamante può richiedere che gli identificatori hardware del dispositivo siano inclusi nei metadati del certificato di attestazione. Se la chiave è conservata nel TEE, il certificato ricollegherà a una radice di attendibilità nota. Il destinatario di tale certificato può verificare che il certificato e il suo contenuto, inclusi gli identificatori hardware, siano stati scritti dal TEE. Quando viene richiesto di includere gli identificatori hardware nel certificato di attestazione, il TEE attesta solo gli identificatori conservati nel suo archivio, come popolato in fabbrica.

Proprietà di archiviazione

La memoria che contiene gli identificatori del dispositivo deve avere queste proprietà:

  • I valori derivati ​​dagli identificatori originali del dispositivo vengono copiati nella memoria prima che il dispositivo lasci la fabbrica.
  • Il metodo destroyAttestationIds() può distruggere definitivamente questa copia dei dati derivati ​​dall'identificatore. Distruzione permanente significa che i dati vengono completamente rimossi in modo che né un ripristino delle impostazioni di fabbrica né alcuna altra procedura eseguita sul dispositivo possano ripristinarli. Ciò è particolarmente importante per i dispositivi in ​​cui un utente ha sbloccato il bootloader e modificato il software di sistema e modificato gli identificatori restituiti dai framework Android.
  • Le strutture RMA dovrebbero avere la capacità di generare nuove copie dei dati derivati ​​dall'identificatore hardware. In questo modo, un dispositivo che passa attraverso RMA può eseguire nuovamente l'attestazione dell'ID. Il meccanismo utilizzato dalle strutture RMA deve essere protetto in modo che gli utenti non possano invocarlo da soli, in quanto ciò consentirebbe loro di ottenere attestazioni di ID contraffatti.
  • Nessun codice diverso dall'app fidata di Keymaster nel TEE è in grado di leggere i dati derivati ​​dall'identificatore conservati nella memoria.
  • La conservazione è a prova di manomissione: se il contenuto della memoria è stato modificato, il TEE lo tratta come se le copie del contenuto fossero state distrutte e rifiuta tutti i tentativi di attestazione dell'identità. Ciò viene implementato firmando o contrassegnando con MAC l'archiviazione come descritto di seguito .
  • La memoria non contiene gli identificatori originali. Poiché l'attestazione dell'ID comporta una sfida, il chiamante fornisce sempre gli identificatori da attestare. Il TEE deve solo verificare che questi corrispondano ai valori che avevano originariamente. L'archiviazione di hash protetti dei valori originali anziché dei valori consente questa verifica.

Costruzione

Per creare un'implementazione con le proprietà sopra elencate, archiviare i valori derivati ​​dall'ID nella seguente costruzione S. Non archiviare altre copie dei valori ID, ad eccezione delle normali posizioni nel sistema, che un proprietario del dispositivo può modificare eseguendo il rooting:

S = D || HMAC(HBK, D)

Dove:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC è la costruzione HMAC con un hash sicuro appropriato (consigliato SHA-256)
  • HBK è una chiave legata all'hardware non utilizzata per altri scopi
  • ID 1 ...ID n sono i valori ID originali; l'associazione di un particolare valore a un particolare indice dipende dall'implementazione, poiché dispositivi diversi avranno numeri diversi di identificatori
  • || rappresenta la concatenazione

Poiché gli output HMAC sono di dimensioni fisse, non sono necessarie intestazioni o altre strutture per poter trovare i singoli hash ID o l'HMAC di D. Oltre a controllare i valori forniti per eseguire l'attestazione, le implementazioni devono convalidare S estraendo D da S , calcolando HMAC(HBK, D) e confrontandolo con il valore in S per verificare che nessun singolo ID sia stato modificato/danneggiato. Inoltre, le implementazioni devono utilizzare confronti a tempo costante per tutti i singoli elementi ID e la convalida di S. Il tempo di confronto deve essere costante indipendentemente dal numero di ID forniti e dalla corrispondenza corretta di qualsiasi parte del test.

Identificatori hardware

L'attestazione ID supporta i seguenti identificatori hardware:

  1. Nome del brand, come restituito da Build.BRAND in Android
  2. Nome del dispositivo, come restituito da Build.DEVICE in Android
  3. Nome del prodotto, come restituito da Build.PRODUCT in Android
  4. Nome del produttore, come restituito da Build.MANUFACTURER in Android
  5. Nome del modello, come restituito da Build.MODEL in Android
  6. Numero di serie
  7. IMEI di tutte le radio
  8. MEID di tutte le radio

Per supportare l'attestazione dell'ID dispositivo, un dispositivo attesta questi identificatori. Tutti i dispositivi con Android hanno i primi sei e sono necessari per il funzionamento di questa funzione. Se il dispositivo dispone di radio cellulari integrate, il dispositivo deve supportare anche l'attestazione per gli IMEI e/o i MEID delle radio.

L'attestazione dell'ID viene richiesta eseguendo un'attestazione della chiave e includendo gli identificatori del dispositivo da attestare nella richiesta. Gli identificatori sono contrassegnati come:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

L'identificatore da attestare è una stringa di byte con codifica UTF-8. Questo formato si applica anche agli identificatori numerici. Ogni identificatore da attestare è espresso come una stringa con codifica UTF-8.

Se il dispositivo non supporta l'attestazione dell'ID (o in precedenza era stato chiamato destroyAttestationIds() e il dispositivo non può più attestare i propri ID), qualsiasi richiesta di attestazione della chiave che include uno o più di questi tag ha esito negativo con ErrorCode::CANNOT_ATTEST_IDS .

Se il dispositivo supporta l'attestazione dell'ID e uno o più dei suddetti tag sono stati inclusi in una richiesta di attestazione della chiave, il TEE verifica che l'identificatore fornito con ciascuno dei tag corrisponda alla sua copia degli identificatori hardware. Se uno o più identificatori non corrispondono, l'intera attestazione ha esito negativo con ErrorCode::CANNOT_ATTEST_IDS . È valido per lo stesso tag da fornire più volte. Questo può essere utile, ad esempio, quando si attestano gli IMEI: un dispositivo può avere più radio con più IMEI. Una richiesta di attestazione è valida se il valore fornito con ogni ATTESTATION_ID_IMEI corrisponde a una delle radio del dispositivo. Lo stesso vale per tutti gli altri tag.

Se l'attestazione ha esito positivo, gli ID attestati vengono aggiunti all'estensione dell'attestazione (OID 1.3.6.1.4.1.11129.2.1.17) del certificato di attestazione emesso, utilizzando lo schema di cui sopra . Le modifiche rispetto allo schema di attestazione Keymaster 2 sono in grassetto , con commenti.

API Java

Questa sezione è solo informativa. Gli implementatori di Keymaster non implementano né utilizzano l'API Java. Questo viene fornito per aiutare gli implementatori a capire come la funzione viene utilizzata dalle applicazioni. I componenti del sistema possono usarlo in modo diverso, motivo per cui è fondamentale che questa sezione non sia trattata come normativa.

,

Keystore fornisce un luogo più sicuro per creare, archiviare e utilizzare le chiavi crittografiche in modo controllato. Quando l'archiviazione delle chiavi basata su hardware è disponibile e utilizzata, il materiale della chiave è più sicuro contro l'estrazione dal dispositivo e Keymaster applica restrizioni difficili da sovvertire.

Ciò è vero, tuttavia, solo se è noto che le chiavi dell'archivio chiavi si trovano nell'archiviazione supportata dall'hardware. In Keymaster 1, non c'era modo per le app o i server remoti di verificare in modo affidabile se fosse così. Il demone keystore ha caricato l'HAL keymaster disponibile e ha creduto a qualunque cosa l'HAL dicesse rispetto al supporto hardware delle chiavi.

Per rimediare a questo, Keymaster ha introdottol'attestazione della chiave in Android 7.0 (Keymaster 2) e l'attestazione dell'ID in Android 8.0 (Keymaster 3).

L'attestazione della chiave mira a fornire un modo per determinare con certezza se una coppia di chiavi asimmetriche è supportata dall'hardware, quali sono le proprietà della chiave e quali vincoli vengono applicati al suo utilizzo.

L'attestazione dell'ID consente al dispositivo di fornire una prova dei propri identificatori hardware, come il numero di serie o l'IMEI.

Attestazione chiave

Per supportare l'attestazione della chiave, Android 7.1 ha introdotto un set di tag, tipo e metodo nell'HAL.

Tag

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Tipo

Keymaster 2 e versioni precedenti

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

Metodo AttestKey

Maestro delle chiavi 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 e versioni precedenti

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev è la struttura del dispositivo keymaster.
  • keyToAttest è il BLOB di chiavi restituito da generateKey per il quale verrà creata l'attestazione.
  • attestParams è un elenco di tutti i parametri necessari per l'attestazione. Questo include Tag::ATTESTATION_CHALLENGE ed eventualmente Tag::RESET_SINCE_ID_ROTATION , così come Tag::APPLICATION_ID e Tag::APPLICATION_DATA . Gli ultimi due sono necessari per decrittografare il BLOB di chiavi se sono stati specificati durante la generazione della chiave.
  • certChain è il parametro di output, che restituisce un array di certificati. La voce 0 è il certificato di attestazione, ovvero certifica la chiave da keyToAttest e contiene l'estensione dell'attestazione.

Il metodo attestKey è considerato un'operazione di chiave pubblica sulla chiave attestata, perché può essere chiamato in qualsiasi momento e non deve soddisfare vincoli di autorizzazione. Ad esempio, se la chiave attestata richiede l'autenticazione dell'utente per l'utilizzo, è possibile generare un'attestazione senza l'autenticazione dell'utente.

Certificato di attestazione

Il certificato di attestazione è un certificato X.509 standard, con un'estensione di attestazione facoltativa che contiene una descrizione della chiave attestata. Il certificato è firmato con una chiave di attestazione certificata. La chiave di attestazione può utilizzare un algoritmo diverso rispetto alla chiave da attestare.

Il certificato di attestazione contiene i campi nella tabella seguente e non può contenere campi aggiuntivi. Alcuni campi specificano un valore di campo fisso. I test CTS convalidano che il contenuto del certificato è esattamente come definito.

SEQUENZA certificato

Nome del campo (vedi RFC 5280 ) Valore
tbsCertificate Certificato TBS SEQUENCE
signatureAlgorithm AlgorithmIdentifier dell'algoritmo utilizzato per firmare la chiave:
ECDSA per chiavi EC, RSA per chiavi RSA.
firmaValore STRINGA DI BIT, firma calcolata su tbsCertificate con codifica DER ASN.1.

Certificato TBS SEQUENCE

Nome del campo (vedi RFC 5280 ) Valore
version INTEGER 2 (indica certificato v3)
serialNumber INTEGER 1 (valore fisso: uguale su tutti i certificati)
signature AlgorithmIdentifier dell'algoritmo utilizzato per firmare la chiave: ECDSA per le chiavi EC, RSA per le chiavi RSA.
issuer Uguale al campo oggetto della chiave di attestazione batch.
validity SEQUENCE di due date, contenente i valori di Tag::ACTIVE_DATETIME e Tag::USAGE_EXPIRE_DATETIME . Questi valori sono espressi in millisecondi dal 1 gennaio 1970. Vedere RFC 5280 per le rappresentazioni corrette della data nei certificati.
Se Tag::ACTIVE_DATETIME non è presente, utilizza il valore di Tag::CREATION_DATETIME . Se Tag::USAGE_EXPIRE_DATETIME non è presente, utilizzare la data di scadenza del certificato della chiave di attestazione batch.
subject CN = "Android Keystore Key" (valore fisso: uguale su tutti i certificati)
subjectPublicKeyInfo SubjectPublicKeyInfo contenente la chiave pubblica attestata.
extensions/Key Usage digitalSignature: imposta se la chiave ha uno scopo KeyPurpose::SIGN o KeyPurpose::VERIFY . Tutti gli altri bit non impostati.
extensions/CRL Distribution Points Valore da definire
extensions/"attestation" L'OID è 1.3.6.1.4.1.11129.2.1.17; il contenuto è definito nella sezione Estensione attestazione di seguito. Come per tutte le estensioni di certificato X.509, il contenuto è rappresentato come OCTET_STRING contenente una codifica DER dell'attestazione SEQUENCE.

Estensione attestazione

L'estensione attestation contiene una descrizione completa delle autorizzazioni del keymaster associate alla chiave, in una struttura che corrisponde direttamente agli elenchi di autorizzazioni utilizzati in Android e nel keymaster HAL. Ogni tag in un elenco di autorizzazioni è rappresentato da una voce ASN.1 SEQUENCE , contrassegnata esplicitamente con il numero di tag keymaster, ma con il descrittore del tipo (quattro bit di ordine elevato) mascherato.

Ad esempio, in Keymaster 3, Tag::PURPOSE è definito in types.hal come ENUM_REP | 1 . Per l'estensione dell'attestazione, il valore ENUM_REP viene rimosso, lasciando il tag 1 . (Per Keymaster 2 e precedenti, KM_TAG_PURPOSE è definito in keymaster_defs.h.)

I valori vengono tradotti in modo semplice nei tipi ASN.1, secondo questa tabella:

Tipo di maestro di chiavi Tipo ASN.1
ENUM NUMERO INTERO
ENUM_REP INSIEME di INTERI
UINT NUMERO INTERO
UINT_REP INSIEME di INTERI
ULONG NUMERO INTERO
ULONG_REP INSIEME di INTERI
DATE INTEGER (millisecondi dal 1 gennaio 1970 00:00:00 GMT)
BOOL NULL (in keymaster, tag presente significa vero, assente significa falso.
La stessa semantica si applica alla codifica ASN.1)
BIGNUM Attualmente non utilizzato, quindi non è definita alcuna mappatura
BYTES OCTET_STRING

Schema

Il contenuto dell'estensione dell'attestazione è descritto dal seguente schema ASN.1.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

Campi KeyDescription

I campi keymasterVersion e attestationChallenge sono identificati in modo posizionale, anziché in base al tag, quindi i tag nella forma codificata specificano solo il tipo di campo. I campi rimanenti sono contrassegnati in modo implicito come specificato nello schema.

Nome del campo Tipo Valore
attestationVersion NUMERO INTERO Versione dello schema di attestazione: 1, 2 o 3.
attestationSecurity Livello di sicurezza Il livello di sicurezza di questa attestazione. È possibile ottenere attestati software di chiavi supportate da hardware. Tali attestazioni non possono essere attendibili se il sistema Android è compromesso.
keymasterVersion NUMERO INTERO Versione del dispositivo keymaster: 0, 1, 2, 3 o 4.
keymasterSecurity Livello di sicurezza Il livello di sicurezza dell'implementazione keymaster.
attestationChallenge OCTET_STRING Valore di Tag::ATTESTATION_CHALLENGE , specificato nella richiesta di attestazione.
uniqueId OCTET_STRING ID univoco facoltativo, presente se la chiave ha Tag::INCLUDE_UNIQUE_ID
softwareEnforced Elenco autorizzazioni Facoltativo, autorizzazioni keymaster che non sono applicate dal TEE, se presenti.
teeEnforced Elenco autorizzazioni Facoltativo, autorizzazioni Keymaster che vengono applicate dal TEE, se presenti.

Campi AuthorizationList

I campi AuthorizationList sono tutti facoltativi e sono identificati dal valore del tag keymaster, con i bit di tipo mascherati. Viene utilizzato il tagging esplicito in modo che i campi contengano anche un tag che indica il loro tipo ASN.1, per facilitare l'analisi.

Per i dettagli sui valori di ciascun campo, vedere types.hal per Keymaster 3 e keymaster_defs.h per Keymaster 2 e versioni successive. I nomi dei tag Keymaster sono stati trasformati in nomi di campo omettendo il prefisso KM_TAG e cambiando il resto in camel case, quindi Tag::KEY_SIZE è diventato keySize .

Campi RootOfTrust

I campi RootOfTrust sono identificati in modo posizionale.

Nome del campo Tipo Valore
verifiedBootKey OCTET_STRING Un hash sicuro della chiave usata per verificare l'immagine del sistema. SHA-256 consigliato.
deviceLocked BOOLEANO Vero se il bootloader è bloccato, il che significa che è possibile eseguire il flashing solo delle immagini firmate e che viene eseguito il controllo di avvio verificato.
verifiedBootState Stato di avvio verificato Stato di avvio verificato.
verifiedBootHash OCTET_STRING Un riepilogo di tutti i dati protetti da Verified Boot. Per i dispositivi che usano l'implementazione Android Verified Boot di Verified Boot, questo valore contiene il digest di VBMeta struct o la struttura dei metadati di Verified Boot. Per ulteriori informazioni su come calcolare questo valore, vedere The VBMeta Digest

Valori VerifiedBootState

I valori verifiedBootState hanno i seguenti significati:

Valore Senso
Verified Indica una catena di attendibilità completa che si estende dal bootloader alle partizioni verificate, inclusi il bootloader, la partizione di avvio e tutte le partizioni verificate.
In questo stato, il verifiedBootKey è l'hash del certificato incorporato, ovvero il certificato non modificabile masterizzato nella ROM.
Questo stato corrisponde allo stato di avvio verde come documentato nella documentazione del flusso di avvio verificato .
SelfSigned Indica che la partizione di avvio è stata verificata utilizzando il certificato incorporato e la firma è valida. Il bootloader visualizza un avviso e l'impronta digitale della chiave pubblica prima di consentire il proseguimento del processo di avvio.
In questo stato, il verifiedBootKey è l'hash del certificato autofirmato.
Questo stato corrisponde allo stato di avvio giallo come documentato nella documentazione del flusso di avvio verificato .
Unverified Indica che un dispositivo può essere liberamente modificato. L'integrità del dispositivo è lasciata all'utente per la verifica fuori banda. Il bootloader visualizza un avviso all'utente prima di consentire il proseguimento del processo di avvio.
In questo stato il verifiedBootKey è vuoto.
Questo stato corrisponde allo stato di avvio arancione come documentato nella documentazione del flusso di avvio verificato .
Failed Indica che il dispositivo non ha superato la verifica. Nessun certificato di attestazione contiene effettivamente questo valore, perché in questo stato il bootloader si arresta. È incluso qui per completezza.
Questo stato corrisponde allo stato di avvio rosso come documentato nella documentazione del flusso di avvio verificato .

Valori SecurityLevel

I valori di securityLevel hanno i seguenti significati:

Valore Senso
Software Il codice che crea o gestisce l'elemento rilevante (attestazione o chiave) è implementato nel sistema Android e potrebbe essere alterato se tale sistema viene compromesso.
TrustedEnvironment Il codice che crea o gestisce l'elemento rilevante (attestazione o chiave) è implementato in un Trusted Execution Environment (TEE). Potrebbe essere alterato se il TEE è compromesso, ma il TEE è altamente resistente alla compromissione remota e moderatamente resistente alla compromissione tramite attacco hardware diretto.
StrongBox Il codice che crea o gestisce l'elemento rilevante (attestato o chiave) è implementato in un modulo di sicurezza hardware dedicato. It could be altered if the hardware security module is compromised, but it is highly resistant to remote compromise and highly resistant to compromise by direct hardware attack.

Unique ID

The Unique ID is a 128-bit value that identifies the device, but only for a limited period of time. The value is computed with:

HMAC_SHA256(T || C || R, HBK)

Where:

  • T is the "temporal counter value", computed by dividing the value of Tag::CREATION_DATETIME by 2592000000, dropping any remainder. T changes every 30 days (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C is the value of Tag::APPLICATION_ID
  • R is 1 if Tag::RESET_SINCE_ID_ROTATION is present in the attest_params parameter to the attest_key call, or 0 if the tag is not present.
  • HBK is a unique hardware-bound secret known to the Trusted Execution Environment and never revealed by it. The secret contains at least 128 bits of entropy and is unique to the individual device (probabilistic uniqueness is acceptable given the 128 bits of entropy). HBK should be derived from fused key material via HMAC or AES_CMAC.

Truncate the HMAC_SHA256 output to 128 bits.

Attestation keys and certificates

Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are securely provisioned into the device.

Android 12 introduces Remote Key Provisioning, and Android 13 requires devices implement it. Remote Key Provisioning provides devices in the field with per-application, ECDSA P256 attestation certificates. These certificates are shorter-lived than the factory-provisioned certificates.

ID attestation

Android 8.0 includes optional support for ID attestation for devices with Keymaster 3. ID attestation allows the device to provide proof of its hardware identifiers, such as serial number or IMEI. Although an optional feature, it is highly recommended that all Keymaster 3 implementations provide support for it because being able to prove the device's identity enables use cases such as true zero-touch remote configuration to be more secure (because the remote side can be certain it is talking to the right device, not a device spoofing its identity).

ID attestation works by creating copies of the device's hardware identifiers that only the Trusted Execution Environment (TEE) can access before the device leaves the factory. A user may unlock the device's bootloader and change the system software and the identifiers reported by the Android frameworks. The copies of the identifiers held by the TEE cannot be manipulated in this way, ensuring that device ID attestation will only ever attest to the device's original hardware identifiers thereby thwarting spoofing attempts.

The main API surface for ID attestation builds on top of the existing key attestation mechanism introduced with Keymaster 2. When requesting an attestation certificate for a key held by keymaster, the caller may request that the device's hardware identifiers be included in the attestation certificate's metadata. If the key is held in the TEE, the certificate will chain back to a known root of trust. The recipient of such a certificate can verify that the certificate and its contents, including the hardware identifiers, were written by the TEE. When asked to include hardware identifiers in the attestation certificate, the TEE attests only to the identifiers held in its storage, as populated on the factory floor.

Storage properties

The storage that holds the device's identifiers needs to have these properties:

  • The values derived from the device's original identifiers are copied to the storage before the device leaves the factory.
  • The destroyAttestationIds() method can permanently destroy this copy of the identifier-derived data. Permanent destruction means the data is completely removed so neither a factory reset nor any other procedure performed on the device can restore it. This is especially important for devices where a user has unlocked the bootloader and changed the system software and modified the identifiers returned by Android frameworks.
  • RMA facilities should have the ability to generate fresh copies of the hardware identifier-derived data. This way, a device that passes through RMA can perform ID attestation again. The mechanism used by RMA facilities must be protected so that users cannot invoke it themselves, as that would allow them to obtain attestations of spoofed IDs.
  • No code other than Keymaster trusted app in the TEE is able to read the identifier-derived data kept in the storage.
  • The storage is tamper-evident: If the content of the storage has been modified, the TEE treats it the same as if the copies of the content had been destroyed and refuses all ID attestation attempts. This is implemented by signing or MACing the storage as described below .
  • The storage does not hold the original identifiers. Because ID attestation involves a challenge, the caller always supplies the identifiers to be attested. The TEE only needs to verify that these match the values they originally had. Storing secure hashes of the original values rather than the values enables this verification.

Construction

To create an implementation that has the properties listed above, store the ID-derived values in the following construction S. Do not store other copies of the ID values, excepting the normal places in the system, which a device owner may modify by rooting:

S = D || HMAC(HBK, D)

where:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC is the HMAC construction with an appropriate secure hash (SHA-256 recommended)
  • HBK is a hardware-bound key not used for any other purpose
  • ID 1 ...ID n are the original ID values; association of a particular value to a particular index is implementation-dependent, as different devices will have different numbers of identifiers
  • || represents concatenation

Because the HMAC outputs are fixed size, no headers or other structure are required to be able to find individual ID hashes, or the HMAC of D. In addition to checking provided values to perform attestation, implementations need to validate S by extracting D from S, computing HMAC(HBK, D) and comparing it to the value in S to verify that no individual IDs were modified/corrupted. Also, implementations must use constant-time comparisons for all individual ID elements and the validation of S. Comparison time must be constant regardless of the number of IDs provided and the correct matching of any part of the test.

Hardware identifiers

ID attestation supports the following hardware identifiers:

  1. Brand name, as returned by Build.BRAND in Android
  2. Device name, as returned by Build.DEVICE in Android
  3. Product name, as returned by Build.PRODUCT in Android
  4. Manufacturer name, as returned by Build.MANUFACTURER in Android
  5. Model name, as returned by Build.MODEL in Android
  6. Numero di serie
  7. IMEIs of all radios
  8. MEIDs of all radios

To support device ID attestation, a device attests to these identifiers. All devices running Android have the first six and they are necessary for this feature to work. If the device has any integrated cellular radios, the device must also support attestation for the IMEIs and/or MEIDs of the radios.

ID attestation is requested by performing a key attestation and including the device identifiers to attest in the request. The identifiers are tagged as:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

The identifier to attest is a UTF-8 encoded byte string. This format applies to numerical identifiers, as well. Each identifier to attest is expressed as a UTF-8 encoded string.

If the device does not support ID attestation (or destroyAttestationIds() was previously called and the device can no longer attest its IDs), any key attestation request that includes one or more of these tags fails with ErrorCode::CANNOT_ATTEST_IDS .

If the device supports ID attestation and one or more of the above tags have been included in a key attestation request, the TEE verifies the identifier supplied with each of the tags matches its copy of the hardware identifiers. If one or more identifiers do not match, the entire attestation fails with ErrorCode::CANNOT_ATTEST_IDS . It is valid for the same tag to be supplied multiple times. This can be useful, for example, when attesting IMEIs: A device may have multiple radios with multiple IMEIs. An attestation request is valid if the value supplied with each ATTESTATION_ID_IMEI matches one of the device's radios. The same applies to all other tags.

If attestation is successful, the attested IDs is added to the attestation extension (OID 1.3.6.1.4.1.11129.2.1.17) of the issued attestation certificate, using the schema from above . Changes from the Keymaster 2 attestation schema are bolded , with comments.

Java API

This section is informational only. Keymaster implementers neither implement nor use the Java API. This is provided to help implementers understand how the feature is used by applications. System components may use it differently, which is why it's crucial this section not be treated as normative.