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, cihazı savunmasız sürüme geri döndüremez ve daha yeni sürümle oluşturulan anahtarları kullanamaz. 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 anahtar kullanılmadan ö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.

Keymaster 4, Treble'ın modüler yapısını desteklemek ve system.img'nin boot.img'ye bağlanmasını engellemek için anahtar sürümü bağlama modelini değiştirerek her bölüm için ayrı yama düzeyleri kullanmaya başladı. Bu sayede, geri çekme 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 Verified Boot (AVB) özellikli 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 karma değerini sağlaması gerekir. Böylece bootloader, karma değerini 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ış Önyükleme tarafından doğrulanan tüm verilerin karma değerini Keymaster'a sağlayabilir.
  • Android 9'da aşağıdaki bölümlerin sürüm bilgilerini sağlamak için 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 sistem görüntüsünün yeni işletim sistemi sürümüne ve 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ın yükseltilmesi 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. Yama seviyesi mevcut sistem değerinden büyük olan bir anahtarla çağrılırsa ErrorCode::INVALID_ARGUMENT döndürülür. OS sürümü mevcut sistem değerinden büyük olan 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 blob'u döndürür.

keyBlobToUpgrade, upgradeKey aramadan 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 etiketinde Tag::ROLLBACK_RESISTANT etiketi varsa upgradedKeyBlob etiketinde de bu etiket olmalıdır (ve geri alma işlemine karşı dirençli 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. Önyükleme görüntüsü oluşturma komut dosyası bu alanı otomatik olarak doldurur. OEM'ler ve Keymaster TA uygulayıcıları, cihaz önyükleyicilerini değiştirerek önyükleme görüntüsünden sürüm bilgilerini ayıklamak ve güvenli olmayan sistem önyüklenmeden önce bu bilgileri TA'ya iletmek için birlikte çalışmalıdır. Bu sayede saldırganlar, TA'ya sürüm bilgilerinin sağlanmasına müdahale edemez.

Sistem görüntüsünün, önyükleme görüntüsüyle aynı sürüm bilgilerine sahip olduğundan da emin olmanız gerekir. Bu amaçla, Keymaster HAL'ye yapılandırma yöntemi eklendi:

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 yönteminden önce başka bir yöntem çağrılırsa TA, ErrorCode::KEYMASTER_NOT_CONFIGURED değerini 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 değerini döndürür ve diğer Keymaster yöntemleri normal şekilde çalışmaya başlar.

configure işlevine yapılan 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 istediği 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. Önyükleme 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.