Associazione versione

In Keymaster 1, tutte le chiavi keymaster erano associate tramite crittografia al dispositivo. Root di attendibilità o la chiave di avvio verificato. In Keymaster 2 e 3, sono associate anche al sistema operativo e al livello di patch dell'immagine di sistema. In questo modo, un aggressore che scopre un punto debole in un vecchio del sistema o del software TEE non può eseguire il rollback di un dispositivo e utilizzare le chiavi create con la versione più recente. Inoltre, quando una chiave con una determinata versione e un determinato livello di patch viene usato su un dispositivo di cui è stato eseguito l'upgrade a una versione o a un livello patch più recente, la chiave viene aggiornata prima di poter essere utilizzata, e la versione precedente della chiave invalidata. In questo modo, dato che il dispositivo aggiornato, le chiavi "a cricchetto" avanti insieme al dispositivo, ma qualsiasi il ripristino del dispositivo a una release precedente fa sì che i tasti vengano inutilizzabile.

per supportare la struttura modulare di Treble e interrompere l'associazione di system.img a boot.img, Keymaster 4 ha modificato il modello di associazione della versione della chiave in modo da avere i livelli di patch per ogni partizione. In questo modo, ogni partizione viene aggiornata in modo indipendente, pur continuando a garantire la protezione dal rollback.

In Android 9, boot, system e vendor ciascuna delle partizioni ha il proprio livello di patch.

  • I dispositivi con Avvio verificato di Android possono applicare tutti i livelli di patch e la versione di sistema in vbmeta, in modo che il bootloader possa fornire Keymaster. Per le partizioni concatenate, le informazioni sulla versione della partizione essere nel vbmeta concatenato. In generale, le informazioni sulla versione devono essere vbmeta struct contenente i dati di verifica (hash o hashtree) per una data partizione.
  • Sui dispositivi senza AVB:
    • Le implementazioni dell'Avvio verificato devono fornire un hash della versione metadati al bootloader, in modo che il bootloader possa fornire l'hash a Keymaster.
    • boot.img può continuare ad archiviare il livello di patch nell'intestazione
    • system.img può continuare ad archiviare a livello di patch e versione del sistema operativo in sola lettura proprietà
    • vendor.img archivia il livello di patch nella proprietà di sola lettura ro.vendor.build.version.security_patch.
    • Il bootloader può fornire un hash di tutti i dati convalidati dall'avvio verificato al keymaster.
  • In Android 9, utilizza i seguenti tag per fornire informazioni sulla versione per le seguenti partizioni:
    • VENDOR_PATCH_LEVEL: vendor partizione
    • BOOT_PATCH_LEVEL: boot partizione
    • OS_PATCH_LEVEL e OS_VERSION: system partizione. (OS_VERSION è stato rimosso da l'intestazione boot.img.
  • Le implementazioni Keymaster devono trattare tutti i livelli delle patch in modo indipendente. Le chiavi sono utilizzabile se tutte le informazioni sulla versione corrispondono ai valori associati a una chiave e IKeymaster::upgradeDevice() passa a un livello patch più alto se necessaria.

Modifiche all'HAL

Per supportare l'associazione della versione e l'attestazione della versione, Android 7.1 ha aggiunto il parametro i tag Tag::OS_VERSION, Tag::OS_PATCHLEVEL e i tag i metodi configure e upgradeKey. I tag di versione vengono aggiunti automaticamente dalle implementazioni Keymaster 2 o versioni successive a tutte le nuove implementazioni (o aggiornate). Inoltre, qualsiasi tentativo di utilizzare una chiave che non ha un sistema operativo di versione o di patch corrispondente all'attuale versione del sistema operativo o al livello di patch, viene rispettivamente rifiutata con ErrorCode::KEY_REQUIRES_UPGRADE.

Tag::OS_VERSION è un valore UINT che rappresenta il le parti maggiore, minore e minore di una versione di un sistema Android come MMmmss, dove MM è la versione principale, mm è la versione secondaria e ss è la versione secondaria completamente gestita. Ad esempio 6.1.2 viene rappresentato come 060102.

Tag::OS_PATCHLEVEL è un valore UINT che rappresenta il l'anno e il mese dell'ultimo aggiornamento del sistema nel formato AAAAMM, dove AAAA è il valore l'anno a quattro cifre e MM il mese di due cifre. Ad esempio, marzo 2016 sarebbe è 201603.

Chiave di upgrade

Consentire l'upgrade delle chiavi alla nuova versione del sistema operativo e al nuovo livello di patch del sistema. immagine, Android 7.1 ha aggiunto il metodo upgradeKey all'HAL:

Keymaster 3

    upgradeKey(vec keyBlobToUpgrade, vec upgradeParams)
        generates(ErrorCode error, vec upgradedKeyBlob);

Keymaster 2

keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
    const keymaster_key_blob_t* key_to_upgrade,
    const keymaster_key_param_set_t* upgrade_params,
    keymaster_key_blob_t* upgraded_key);
  • dev è la struttura del dispositivo
  • keyBlobToUpgrade è la chiave di cui deve essere eseguito l'upgrade
  • upgradeParams sono parametri necessari per eseguire l'upgrade della chiave. Questi includerà Tag::APPLICATION_ID e Tag::APPLICATION_DATA, necessari per decriptare la chiave se forniti durante la generazione.
  • upgradedKeyBlob è il parametro di output, utilizzato per restituire il valore nuovo BLOB di chiave.

Se upgradeKey viene chiamato con un blob della chiave che non può essere analizzato o non è valido, restituisce ErrorCode::INVALID_KEY_BLOB. Se viene chiamato con una chiave il cui livello di patch è maggiore del valore di sistema corrente, restituisce ErrorCode::INVALID_ARGUMENT. Se viene chiamato con una chiave la cui versione del sistema operativo è superiore al valore di sistema corrente e il valore di sistema è diverso da zero, restituisce ErrorCode::INVALID_ARGUMENT. Versione del sistema operativo sono consentiti gli upgrade da un valore diverso da zero a zero. In caso di errori comunica con il mondo sicuro, restituisce un valore di errore appropriato (ad es. ErrorCode::SECURE_HW_ACCESS_DENIED, ErrorCode::SECURE_HW_BUSY). In caso contrario, restituisce ErrorCode::OK e restituisce un nuovo blob di chiave in upgradedKeyBlob.

keyBlobToUpgrade rimane valido dopo il upgradeKey e potrebbe teoricamente essere riutilizzato in caso di downgrade del dispositivo. Nella pratica, l'archivio chiavi di solito chiama deleteKey blob keyBlobToUpgrade poco dopo la chiamata a upgradeKey. Se keyBlobToUpgrade avesse un tag Tag::ROLLBACK_RESISTANT, poi upgradedKeyBlob dovrebbe (e deve essere resistente al rollback).

Configurazione sicura

Per implementare l'associazione della versione, il keymaster TA ha bisogno di un modo per ricevere in modo sicuro la versione corrente del sistema operativo e il livello di patch (informazioni sulla versione) e di garantire che riceve informazioni altamente corrispondenti a quelle sull'esecuzione di un sistema operativo completo.

Per supportare la distribuzione sicura delle informazioni sulla versione all'assistente, è necessario un OS_VERSION è stato aggiunto all'intestazione dell'immagine di avvio. La build dell'immagine di avvio compila automaticamente questo campo. OEM e keymaster TA implementer devono collaborare per modificare i bootloader del dispositivo ed estrarre la versione le informazioni dall'immagine di avvio e passarle all'assistente prima che in fase di avvio del sistema. In questo modo si garantisce che i malintenzionati non possano interferire con il provisioning delle informazioni sulla versione all'assistente.

È inoltre necessario garantire che l'immagine di sistema abbia la stessa versione informazioni come immagine di avvio. A questo scopo, è stato aggiunto il metodo di configurazione al keymaster HAL:

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

L'argomento params contiene Tag::OS_VERSION e Tag::OS_PATCHLEVEL. Questo metodo viene chiamato dai client keymaster2 dopo l'apertura dell'HAL, ma prima di chiamare qualsiasi altro metodo. Se un altro metodo è prima di eseguire la configurazione, l'AT restituisce ErrorCode::KEYMASTER_NOT_CONFIGURED.

La prima volta che configure viene chiamato dopo l'avvio del dispositivo, deve verificare che le informazioni fornite sulla versione corrispondano a quelle fornite il bootloader. Se le informazioni sulla versione non corrispondono, configure restituisce ErrorCode::INVALID_ARGUMENT e tutti i dispositivi altri metodi keymaster continuano a restituire ErrorCode::KEYMASTER_NOT_CONFIGURED. Se le informazioni corrispondono, configure restituisce ErrorCode::OK e altro keymaster iniziano a funzionare normalmente.

Le chiamate successive a configure restituiscono lo stesso valore restituito dal prima chiamata e non modificare lo stato di keymaster. Tieni presente che questo processo richiede che tutti gli OTA aggiornino sia le immagini di sistema che quelle di avvio; non possono essere aggiornati separatamente per mantenere sincronizzate le informazioni sulla versione.

Perché configure verrà chiamato dal sistema di cui è il contenuto volta a convalidare, esiste una finestra di opportunità ristretta per un aggressore compromettere l'immagine di sistema e costringerla a fornire informazioni sulla versione che corrisponde all'immagine di avvio, ma che non è la versione effettiva del sistema. La combinazione di verifica dell'immagine di avvio, convalida di verifica dm dell'immagine di sistema contenuti; inoltre, il fatto che configure venga chiamato molto presto l'avvio del sistema dovrebbe rendere questa finestra di opportunità difficile da sfruttare.