Attestazione chiave e identità

Keystore fornisce un luogo più sicuro in cui creare, archiviare e utilizzare le chiavi crittografiche in modo controllato. Quando è disponibile e utilizzata la memorizzazione delle chiavi supportata da hardware, 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 nello spazio di archiviazione supportato da hardware. In Keymaster 1, le app o i server remoti non avevano modo di verificare in modo affidabile se fosse così. Il demone del keystore caricava l'HAL keymaster disponibile e credeva a qualunque cosa dicesse l'HAL rispetto al supporto hardware delle chiavi.

Per rimediare a questo problema, Keymaster ha introdotto l'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 la 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. Ciò include Tag::ATTESTATION_CHALLENGE e possibilmente Tag::RESET_SINCE_ID_ROTATION , nonché 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 di attestazione.

Il metodo attestKey è considerato un'operazione di chiave pubblica sulla chiave attestata, perché può essere chiamato in qualsiasi momento e non necessita di soddisfare vincoli di autorizzazione. Se, ad esempio, la chiave attestata necessita dell'autenticazione dell'utente per l'uso, è 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 della tabella seguente e non può contenere campi aggiuntivi. Alcuni campi specificano un valore di campo fisso. I test CTS confermano che il contenuto del certificato è esattamente quello definito.

SEQUENZA del certificato

Nome del campo (vedi RFC 5280 ) Valore
tbsCertificate SEQUENZA del certificato TBS
firmaAlgoritmo AlgorithmIdentificatore dell'algoritmo utilizzato per firmare la chiave:
ECDSA per chiavi EC, RSA per chiavi RSA.
valorefirma BIT STRING, firma calcolata su tbsCertificate con codifica ASN.1 DER.

SEQUENZA del certificato TBS

Nome del campo (vedi RFC 5280 ) Valore
version INTEGER 2 (significa certificato v3)
serialNumber INTEGER 1 (valore fisso: uguale su tutti i certificati)
signature AlgorithmIdentificatore dell'algoritmo utilizzato per firmare la chiave: ECDSA per chiavi EC, RSA per chiavi RSA.
issuer Uguale al campo oggetto della chiave di attestazione batch.
validity SEQUENZA 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. Consulta RFC 5280 per la rappresentazione corretta 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 ObjectPublicKeyInfo 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 dell'attestazione di seguito. Come per tutte le estensioni del certificato X.509, il contenuto è rappresentato come OCTET_STRING contenente una codifica DER della SEQUENCE di attestazione.

Estensione dell'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 nell'HAL del keymaster. Ciascun tag in un elenco di autorizzazioni è rappresentato da una voce ASN.1 SEQUENCE , contrassegnata esplicitamente con il numero del tag keymaster, ma con il descrittore del tipo (quattro bit di ordine superiore) mascherato.

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

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

Tipo maestro delle chiavi Tipo ASN.1
ENUM NUMERO INTERO
ENUM_REP SET di INTERI
UINT NUMERO INTERO
UINT_REP SET di INTERI
ULONG NUMERO INTERO
ULONG_REP SET di INTERI
DATE INTERO (millisecondi dal 1 gennaio 1970 00:00:00 GMT)
BOOL NULL (in keymaster, il 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 OTTET_STRING

Schema

Il contenuto dell'estensione di 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 posizionalmente, anziché tramite tag, quindi i tag nel modulo codificato specificano solo il tipo di campo. I campi rimanenti sono contrassegnati implicitamente 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 attestazioni software delle 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 del keymaster.
attestationChallenge OTTET_STRING Valore di Tag::ATTESTATION_CHALLENGE , specificato nella richiesta di attestazione.
uniqueId OTTET_STRING ID univoco facoltativo, presente se la chiave ha Tag::INCLUDE_UNIQUE_ID
softwareEnforced Elencoautorizzazioni Facoltativo, autorizzazioni del keymaster che non vengono applicate dal TEE, se presenti.
teeEnforced Elencoautorizzazioni Facoltativo, autorizzazioni Keymaster applicate dal TEE, se presenti.

Campi AuthorizationList

I campi AuthorizationList sono tutti facoltativi e sono identificati dal valore del tag keymaster, con i bit del tipo mascherati. Viene utilizzata la codifica esplicita in modo che i campi contengano anche un tag che indica il tipo ASN.1, per un'analisi più semplice.

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

Campi RootOfTrust

I campi RootOfTrust sono identificati posizionalmente.

Nome del campo Tipo Valore
verifiedBootKey OTTET_STRING Un hash sicuro della chiave utilizzato per verificare l'immagine del sistema. Consigliato SHA-256.
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 dell'avvio verificato.
verifiedBootState Stato di avvio verificato Stato di avvio verificato.
verifiedBootHash OTTET_STRING Un riepilogo di tutti i dati protetti da Verified Boot. Per i dispositivi che utilizzano l'implementazione Android Verified Boot di Verified Boot, questo valore contiene il digest della struttura VBMeta o la struttura dei metadati Verified Boot. Per ulteriori informazioni su come calcolare questo valore, vedereThe VBMeta Digest

Valori VerifiedBootState

I valori di verifiedBootState hanno i seguenti significati:

Valore Senso
Verified Indica una catena di fiducia completa che si estende dal bootloader alle partizioni verificate, incluso il bootloader, la partizione di avvio e tutte le partizioni verificate.
In questo stato, il valore verifiedBootKey è l'hash del certificato incorporato, ovvero il certificato immutabile 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 la continuazione del processo di avvio.
In questo stato, il valore 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 modificato liberamente. L'integrità del dispositivo è lasciata all'utente per la verifica fuori banda. Il bootloader visualizza un avviso all'utente prima di consentire al processo di avvio di continuare.
In questo stato il valore 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 ferma. È incluso qui per completezza.
Questo stato corrisponde allo stato di avvio rosso come documentato nella documentazione del flusso di avvio verificato .

Valori del livello di sicurezza

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 modificato 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 modificato se il TEE viene 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 (attestazione o chiave) è implementato in un modulo di sicurezza hardware dedicato. Potrebbe essere modificato 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 si calcola 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 l'eventuale 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 nella chiamata attest_key o 0 se il tag non è presente.
  • HBK è un segreto unico 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 deve essere derivato dal materiale della chiave fusa tramite HMAC o AES_CMAC.

Tronca l'output HMAC_SHA256 a 128 bit.

Chiavi e certificati di attestazione

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

Android 12 introduce il provisioning delle chiavi remote e Android 13 richiede che i dispositivi lo implementino. Il provisioning delle chiavi remote 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.

IMEI multipli

Android 14 aggiunge il supporto per più IMEI nel record di attestazione della chiave Android. Gli OEM possono implementare questa funzionalità aggiungendo un tag KeyMint per un secondo IMEI. Sta diventando sempre più comune che i dispositivi dispongano di più radio cellulari e gli OEM ora possono supportare dispositivi con due IMEI.

Gli OEM sono tenuti ad avere un IMEI secondario, se presente sui loro dispositivi, da fornire alle implementazioni KeyMint in modo che tali implementazioni possano attestarlo nello stesso modo in cui attestano il primo IMEI

Attestazione di identità

Android 8.0 include il supporto opzionale per l'attestazione dell'ID per i dispositivi con Keymaster 3. L'attestazione dell'ID consente al dispositivo di fornire una prova dei propri 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 poiché essere in grado di dimostrare l'identità del dispositivo consente casi d'uso come la vera configurazione remota zero-touch per essere più sicuri (perché il lato remoto può essere certo che sia sta comunicando con il dispositivo giusto, non con un dispositivo che falsifica la propria identità).

L'attestazione dell'ID funziona creando copie degli identificatori hardware del dispositivo a cui solo il Trusted Execution Environment (TEE) 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 conservati dal TEE non possono essere manipolate in questo modo, garantendo che l'attestazione dell'ID del dispositivo attesterà sempre e solo gli identificatori hardware originali del dispositivo, contrastando 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 verrà ricollegato 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, così come popolati in fabbrica.

Proprietà di archiviazione

Lo spazio di archiviazione 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 permanentemente questa copia dei dati derivati ​​dall'identificatore. La distruzione permanente significa che i dati vengono completamente rimossi in modo che né un ripristino delle impostazioni di fabbrica né qualsiasi altra procedura eseguita sul dispositivo possa ripristinarli. Ciò è particolarmente importante per i dispositivi in ​​cui un utente ha sbloccato il bootloader, modificato il software di sistema e modificato gli identificatori restituiti dai framework Android.
  • Le strutture RMA dovrebbero essere in grado 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, poiché ciò consentirebbe loro di ottenere attestazioni di ID falsificati.
  • Nessun codice diverso dall'app attendibile Keymaster nel TEE è in grado di leggere i dati derivati ​​dall'identificatore conservati nell'archivio.
  • L'archivio è a prova di manomissione: se il contenuto dell'archivio è 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 effettuando il MAC dello spazio di archiviazione come descritto di seguito .
  • L'archivio non conserva 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 degli hash sicuri dei valori originali anziché dei valori consente questa verifica.

Costruzione

Per creare un'implementazione che abbia le proprietà elencate sopra, archivia 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 nessun altro scopo
  • ID 1 ...ID n sono i valori ID originali; l'associazione di un valore particolare a un indice particolare dipende dall'implementazione, poiché dispositivi diversi avranno numeri diversi di identificatori
  • || rappresenta la concatenazione

Poiché gli output HMAC hanno 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 ID individuale sia stato modificato/corrotto. 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 corretta corrispondenza di qualsiasi parte del test.

Identificatori hardware

L'attestazione ID supporta i seguenti identificatori hardware:

  1. Nome del marchio, 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 affinché questa funzione funzioni. Se il dispositivo dispone di radio cellulari integrate, il dispositivo deve supportare anche l'attestazione degli IMEI e/o MEID delle radio.

L'attestazione dell'ID viene richiesta eseguendo un'attestazione 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 codificata UTF-8. Questo formato si applica anche agli identificatori numerici. Ogni identificatore da attestare è espresso come stringa con codifica UTF-8.

Se il dispositivo non supporta l'attestazione dell'ID (o è stato chiamato in precedenza 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 tag di cui sopra 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 fallisce con ErrorCode::CANNOT_ATTEST_IDS . È valido che lo stesso tag venga fornito più volte. Ciò 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 ciascun 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 di 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 e accompagnate da commenti.

API Java

Questa sezione è solo informativa. Gli implementatori Keymaster non implementano né utilizzano l'API Java. Questo viene fornito per aiutare gli implementatori a comprendere come la funzionalità viene utilizzata dalle applicazioni. I componenti del sistema potrebbero utilizzarlo in modo diverso, motivo per cui è fondamentale che questa sezione non venga trattata come normativa.