Sürüm bağlama

Keymaster 1'de tüm Keymaster anahtarları, cihazın Root of Trust'una veya Doğrulanmış Önyükleme anahtarına kriptografik olarak bağlıydı. Keymaster 2 ve 3'te tüm anahtarlar, sistem görüntüsünün işletim sistemine ve yama düzeyine de bağlıdır. Bu sayede, sistemin veya TEE yazılımının eski bir sürümündeki zafiyeti keşfeden bir saldırganın cihazı savunmasız sürüme geri döndürememesi ve daha yeni sürümle oluşturulan anahtarları kullanamaması sağlanır. Ayrıca, belirli bir sürüm ve yama düzeyine sahip bir anahtar, daha yeni bir sürüme veya yama düzeyine yükseltilmiş bir cihazda kullanıldığında, kullanılabilmesi için önce yükseltilir ve anahtarın önceki sürümü geçersiz kılınır. Bu şekilde, cihaz yükseltildikçe anahtarlar da cihazla birlikte ileriye doğru *ilerler*. Ancak cihazın önceki bir sürüme geri döndürülmesi, anahtarların kullanılamaz hale gelmesine neden olur.

Treble'ın modüler yapısını desteklemek ve system.img'nin boot.img'ye bağlanmasını engellemek için Keymaster 4, anahtar sürümü bağlama modelini her bölüm için ayrı yama düzeylerine sahip olacak şekilde değiştirdi. Bu sayede, geri alma koruması sağlanmaya devam ederken her bölüm bağımsız olarak güncellenebilir.

Bu sürüm bağlamayı uygulamak için KeyMint güvenilir uygulamasının (TA) mevcut işletim sistemi sürümünü ve yama düzeylerini güvenli bir şekilde alması ve aldığı bilgilerin, çalışan sistemle ilgili tüm bilgilerle eşleşmesini sağlaması gerekir.

  • Android Doğrulanmış Başlatma (AVB) özelliğine sahip cihazlar, tüm yama düzeylerini ve sistem sürümünü vbmeta'ya yerleştirebilir. Böylece önyükleyici, bunları Keymaster'a sağlayabilir. Zincirleme bölümlerde, bölümün sürüm bilgileri zincirleme vbmeta'dadır. Genel olarak, sürüm bilgileri belirli bir bölümün doğrulama verilerini (karma veya karma ağacı) içeren vbmeta struct içinde olmalıdır.
  • AVB'nin bulunmadığı cihazlarda:
    • Doğrulanmış başlatma uygulamalarının, bootloader'a sürüm meta verilerinin karmasını sağlaması gerekir. Böylece bootloader, karmayı Keymaster'a sağlayabilir.
    • boot.img, yama düzeyini başlıkta saklamaya devam edebilir.
    • system.img, yama düzeyini ve işletim sistemi sürümünü salt okunur özelliklerde depolamaya devam edebilir.
    • vendor.img, yama düzeyini salt okunur özellik olan ro.vendor.build.version.security_patch içinde saklar.
    • Önyükleyici, Doğrulanmış Başlatma tarafından doğrulanan tüm verilerin Keymaster'a yönelik karma değerini sağlayabilir.
  • Android 9'da aşağıdaki bölümler için sürüm bilgisi sağlamak üzere aşağıdaki etiketleri kullanın:
    • VENDOR_PATCH_LEVEL: vendor bölümü
    • BOOT_PATCH_LEVEL: boot bölümü
    • OS_PATCH_LEVEL ve OS_VERSION: system bölümü. (OS_VERSION, boot.img üstbilgisinden kaldırılır.
  • Keymaster uygulamaları, tüm yama düzeylerini bağımsız olarak ele almalıdır. Tüm sürüm bilgileri bir anahtarla ilişkili değerlerle eşleşiyorsa anahtarlar kullanılabilir ve gerekirse IKeymaster::upgradeDevice() daha yüksek bir yama düzeyine çıkarılır.

HAL değişiklikleri

Android 7.1, sürüm bağlama ve sürüm onayını desteklemek için Tag::OS_VERSION ve Tag::OS_PATCHLEVEL etiketlerini, configure ve upgradeKey yöntemlerini ekledi. Sürüm etiketleri, Keymaster 2+ uygulamaları tarafından yeni oluşturulan (veya güncellenen) tüm anahtarlara otomatik olarak eklenir. Ayrıca, mevcut sistem işletim sistemi sürümü veya yama seviyesiyle eşleşen bir işletim sistemi sürümüne ya da yama seviyesine sahip olmayan bir anahtar kullanma girişimi ErrorCode::KEY_REQUIRES_UPGRADE ile reddedilir.

Tag::OS_VERSION, bir Android sistem sürümünün ana, alt ve daha alt bölümlerini MMmmss olarak gösteren bir UINT değeridir. Burada MM ana sürüm, mm alt sürüm ve ss daha alt sürümdür. Örneğin 6.1.2, 060102 olarak gösterilir.

Tag::OS_PATCHLEVEL, sistemin son güncellemesinin yılını ve ayını YYYYMM olarak gösteren bir UINT değeridir. Burada YYYY dört basamaklı yılı, MM ise iki basamaklı ayı ifade eder. Örneğin, Mart 2016, 201603 olarak gösterilir.

UpgradeKey

Android 7.1, anahtarların yeni işletim sistemi sürümüne ve sistem görüntüsünün yama düzeyine yükseltilmesine izin vermek için HAL'ye upgradeKey yöntemini ekledi:

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, cihaz yapısıdır
  • keyBlobToUpgrade, yükseltilmesi gereken anahtardır
  • upgradeParams, anahtarı yükseltmek için gereken parametrelerdir. Bunlar arasında, oluşturma sırasında sağlanmışsa anahtar blob'unun şifresini çözmek için gerekli olan Tag::APPLICATION_ID ve Tag::APPLICATION_DATA yer alır.
  • upgradedKeyBlob, yeni anahtar blob'unu döndürmek için kullanılan çıkış parametresidir.

upgradeKey, ayrıştırılamayan veya başka bir şekilde geçersiz olan bir anahtar blobuyla çağrılırsa ErrorCode::INVALID_KEY_BLOB döndürülür. Mevcut sistem değerinden daha yüksek bir yama seviyesine sahip anahtarla çağrılırsa ErrorCode::INVALID_ARGUMENT döndürülür. Mevcut sistem değerinden daha büyük bir OS sürümüne sahip bir anahtarla çağrılırsa ve sistem değeri sıfır değilse ErrorCode::INVALID_ARGUMENT değerini döndürür. OS sürümünün sıfır olmayan bir sürümden sıfır sürümüne yükseltilmesine izin verilir. Güvenli dünyayla iletişimde hata olması durumunda uygun bir hata değeri (örneğin, ErrorCode::SECURE_HW_ACCESS_DENIED, ErrorCode::SECURE_HW_BUSY) döndürür. Aksi takdirde ErrorCode::OK değerini döndürür ve upgradedKeyBlob içinde yeni bir anahtar blobu döndürür.

keyBlobToUpgrade, upgradeKey aramasından sonra geçerliliğini korur ve cihazın sürümü düşürülürse teorik olarak tekrar kullanılabilir. Uygulamada, tuş deposu genellikle deleteKey blob'unda upgradeKey çağrısından kısa süre sonra keyBlobToUpgrade çağrısı yapar. keyBlobToUpgrade öğesinde Tag::ROLLBACK_RESISTANT etiketi varsa upgradedKeyBlob öğesinde de bu etiket olmalıdır (ve geri alma işlemine dayanıklı olmalıdır).

Güvenli yapılandırma

Sürüm bağlamayı uygulamak için Keymaster TA'nın mevcut işletim sistemi sürümünü ve yama düzeyini (sürüm bilgileri) güvenli bir şekilde alması ve aldığı bilgilerin, çalışan sistemle ilgili bilgilerle güçlü bir şekilde eşleşmesini sağlaması gerekir.

Sürüm bilgilerinin TA'ya güvenli bir şekilde iletilmesini desteklemek için önyükleme görüntüsü üstbilgisine bir OS_VERSION alanı eklendi. Başlatma görüntüsü oluşturma komut dosyası bu alanı otomatik olarak doldurur. OEM'ler ve Keymaster TA uygulayıcıları, cihaz bootloader'larını değiştirmek için birlikte çalışmalıdır. Böylece, güvenli olmayan sistem başlatılmadan önce başlatma görüntüsünden sürüm bilgileri çıkarılıp TA'ya iletilebilir. Bu sayede saldırganlar, TA'ya sürüm bilgilerinin sağlanmasına müdahale edemez.

Ayrıca, sistem görüntüsünün, başlatma görüntüsüyle aynı sürüm bilgilerine sahip olduğundan emin olmak da gerekir. Bu amaçla, Keymaster HAL'ye yapılandırma yöntemi eklenmiştir:

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

params bağımsız değişkeni Tag::OS_VERSION ve Tag::OS_PATCHLEVEL içeriyor. Bu yöntem, HAL açıldıktan sonra ancak başka bir yöntem çağrılmadan önce keymaster2 istemcileri tarafından çağrılır. configure'dan önce başka bir yöntem çağrılırsa TA, ErrorCode::KEYMASTER_NOT_CONFIGURED döndürür.

Cihaz önyüklendikten sonra configure ilk kez çağrıldığında, sağlanan sürüm bilgilerinin önyükleyici tarafından sağlanan bilgilerle eşleştiğini doğrulamalıdır. Sürüm bilgileri eşleşmezse, configure ErrorCode::INVALID_ARGUMENT değerini döndürür ve diğer tüm Keymaster yöntemleri ErrorCode::KEYMASTER_NOT_CONFIGURED değerini döndürmeye devam eder. Bilgiler eşleşirse, configure ErrorCode::OK döndürülür ve diğer Keymaster yöntemleri normal şekilde çalışmaya başlar.

configure için sonraki çağrılar, ilk çağrının döndürdüğü değeri döndürür ve Keymaster'ın durumunu değiştirmez.

configure, içeriğini doğrulamak için tasarlandığı sistem tarafından çağrıldığından, saldırganın sistem görüntüsünü tehlikeye atıp başlatma görüntüsüyle eşleşen ancak sistemin gerçek sürümü olmayan sürüm bilgilerini sağlamaya zorlaması için dar bir fırsat penceresi vardır. Başlatma görüntüsü doğrulama, sistem görüntüsü içeriklerinin dm-verity doğrulaması ve configure işlevinin sistem önyüklemesinde çok erken çağrılması, bu fırsat penceresinin kötüye kullanılmasını zorlaştırır.