Android 12'den itibaren Android Runtime (ART) modülü bir Mainline modülüdür. Modülün güncellenmesi, bootclasspath jar'larının ve sistem sunucusunun önceden derleme (AOT) derleme yapıtlarının yeniden oluşturulmasını gerektirebilir. Bu yapılar güvenlikle ilgili hassas bilgiler içerdiğinden Android 12, bu yapıların kurcalanmasını önlemek için cihaz üzerinde imzalama adı verilen bir özellik kullanır. Bu sayfada, cihaz üzerinde imzalama mimarisi ve diğer Android güvenlik özellikleriyle etkileşimleri ele alınmaktadır.
Üst düzey tasarım
Cihaz üzerinde imzalama iki temel bileşenden oluşur:
odrefresh, ART Mainline modülünün bir parçasıdır. Çalışma zamanı yapılarını oluşturmaktan sorumludur. Mevcut yapıtları, ART modülünün yüklü sürümü, bootclasspath JAR'ları ve sistem sunucusu JAR'ları ile karşılaştırarak güncel olup olmadıklarını veya yeniden oluşturulmaları gerekip gerekmediğini belirler. Yeniden oluşturulmaları gerekiyorsaodrefreshbunları oluşturup saklar.odsign, Android platformunun bir parçası olan bir ikili programdır./databölümü bağlandıktan hemen sonra, erken başlatma sırasında çalışır. Temel sorumluluğu,odrefresh'ı çağırarak herhangi bir yapının oluşturulması veya güncellenmesi gerekip gerekmediğini kontrol etmektir.odrefreshtarafından oluşturulan yeni veya güncellenmiş tüm yapılar içinodsign, karma işlevi hesaplar. Bu tür bir karma hesaplamasının sonucuna dosya özeti denir. Halihazırda mevcut olan tüm yapılar için,odsign, mevcut yapıların özetlerinin,odsigntarafından daha önce hesaplanan özetlerle eşleştiğini doğrular. Bu sayede, yapay nesnelerin değiştirilmediği doğrulanır.
Bir dosyanın özetinin eşleşmemesi gibi hata durumlarında odrefresh ve odsign, /data üzerindeki mevcut tüm yapıları atar ve bunları yeniden oluşturmaya çalışır. Bu işlem başarısız olursa sistem JIT moduna geri döner.
odrefresh ve odsign, dm-verity tarafından korunur ve Android'in Doğrulanmış Başlatma zincirinin bir parçasıdır.
fs-verity ile dosya özetlerinin hesaplanması
fs-verity, dosya verilerinin Merkle ağacı tabanlı doğrulanmasını sağlayan bir Linux çekirdeği özelliğidir. Bir dosyada fs-verity'nin etkinleştirilmesi, dosya sisteminin SHA-256 karmalarını kullanarak dosyanın verileri üzerinde bir Merkle ağacı oluşturmasına, bunu dosyanın yanında gizli bir konumda saklamasına ve dosyayı salt okunur olarak işaretlemesine neden olur. fs-verity, okunduğu sırada dosyanın verilerini Merkle ağacına göre otomatik olarak doğrular. fs-verity, Merkle ağacının kök karmasını fs-verity dosya özeti adı verilen bir değer olarak kullanılabilir hâle getirir ve fs-verity, dosyadan okunan tüm verilerin bu dosya özetiyle tutarlı olmasını sağlar.
odsign, başlatma sırasında cihazda derlenen yapay nesnelerin kriptografik kimlik doğrulamasını optimize ederek başlatma performansını artırmak için fs-verity'yi kullanır. Bir yapı oluşturulduğunda odsign, üzerinde fs-verity'yi etkinleştirir. odsign, bir yapıyı doğrularken tam dosya karması yerine fs-verity dosya özetini doğrular. Bu sayede, başlatma sırasında yapının tüm verilerinin okunup karma oluşturulması gerekmez. Bunun yerine, yapay ürün verileri, fs-verity tarafından blok bazında, kullanıldıkça isteğe bağlı olarak karma oluşturma işlemine tabi tutulur.
Çekirdeği fs-verity'yi desteklemeyen cihazlarda odsign, kullanıcı alanında dosya özetlerini hesaplamaya geri döner. odsign, fs-verity ile aynı Merkle ağacı tabanlı karma algoritmasını kullandığından özetler her iki durumda da aynıdır.
Android 11 ve sonraki sürümlerle kullanıma sunulan tüm cihazlarda fs-verity gereklidir.
Dosya özetlerinin depolanması
odsign, yapıtların dosya özetlerini odsign.info adlı ayrı bir dosyada saklar. odsign.info ile oynanmadığından emin olmak için odsign.info
önemli güvenlik özelliklerine sahip bir imzalama anahtarıyla imzalanır. Özellikle anahtar yalnızca erken başlatma sırasında oluşturulup kullanılabilir. Bu sırada yalnızca güvenilir kod çalışır. Ayrıntılar için Güvenilir imzalama anahtarları bölümüne bakın.
Dosya özetlerinin doğrulanması
Her başlatma işleminde, odrefresh mevcut yapıların güncel olduğunu belirlerse odsign, dosyaların oluşturuldukları tarihten itibaren değiştirilmediğinden emin olur. odsign, dosya özetlerini doğrulayarak bunu yapar. İlk olarak, odsign.info imzası doğrulanır. İmza geçerliyse odsign, her dosyanın özetinin odsign.info'deki karşılık gelen özetle eşleştiğini doğrular.
Güvenilir imzalama anahtarları
Android 12, aşağıdaki güvenlik sorunlarını ele alan, önyükleme aşaması anahtarları adlı yeni bir Keystore özelliği sunar:
- Saldırganların,
odsign.infouygulamasının kendi sürümünü imzalamak için imzalama anahtarımızı kullanmasını ne engeller? - Saldırganların kendi imzalama anahtarlarını oluşturup
odsign.infouygulamasının kendi sürümlerini imzalamak için kullanmasını ne engeller?
Önyükleme aşaması anahtarları, Android'in önyükleme döngüsünü seviyelere böler ve anahtarın oluşturulmasını ve kullanılmasını belirli bir seviyeye kriptografik olarak bağlar. odsign, yalnızca güvenilir kodun çalıştığı erken bir düzeyde imzalama anahtarını oluşturur. Bu anahtar, dm-verity ile korunur.
Başlatma aşaması seviyeleri 0 ile 1000000000 arasında numaralandırılır. Android'in başlatma işlemi sırasında, init.rc üzerinden bir sistem özelliği ayarlayarak başlatma düzeyini artırabilirsiniz. Örneğin, aşağıdaki kod, önyükleme düzeyini 10 olarak ayarlar:
setprop keystore.boot_level 10
Keystore müşterileri, belirli bir başlatma seviyesine bağlı anahtarlar oluşturabilir. Örneğin, önyükleme düzeyi 10 için bir anahtar oluşturursanız bu anahtar yalnızca cihaz önyükleme düzeyi 10'dayken kullanılabilir.
odsign, önyükleme düzeyi 30'u kullanır ve oluşturduğu imzalama anahtarı bu önyükleme düzeyine bağlıdır. odsign, yapıtları imzalamak için kullanılan anahtarın önyükleme düzeyi 30'a bağlı olduğunu doğrular.
Bu, bu bölümün başlarında açıklanan iki saldırıyı önler:
- Saldırganlar, oluşturulan anahtarı kullanamaz. Bunun nedeni, saldırganın kötü amaçlı kod çalıştırma fırsatı bulduğu sırada önyükleme seviyesinin 30'u aşmış olması ve Keystore'un anahtarı kullanan işlemleri reddetmesidir.
- Saldırganlar yeni bir anahtar oluşturamaz. Bunun nedeni, saldırganın kötü amaçlı kod çalıştırma fırsatı bulduğunda önyükleme düzeyinin 30'u aşmış olması ve Keystore'un bu önyükleme düzeyiyle yeni bir anahtar oluşturmayı reddetmesidir. Saldırgan, önyükleme düzeyi 30 ile ilişkili olmayan yeni bir anahtar oluşturursa
odsignbunu reddeder.
Keystore, önyükleme düzeyinin düzgün şekilde zorunlu kılınmasını sağlar. Aşağıdaki bölümlerde, bunun farklı KeyMint (eski adıyla Keymaster) sürümlerinde nasıl yapıldığı hakkında daha ayrıntılı bilgi verilmektedir.
Keymaster 4.0 uygulaması
Keymaster'ın farklı sürümleri, önyükleme aşaması anahtarlarının uygulanmasını farklı şekilde ele alır. Keymaster 4.0 TEE/StrongBox'a sahip cihazlarda Keymaster, uygulamayı aşağıdaki şekilde yönetir:
- Keystore, ilk başlatmada
MAX_USES_PER_BOOTetiketi1olarak ayarlanmış bir K0 simetrik anahtarı oluşturur. Bu, anahtarın her başlatma işleminde yalnızca bir kez kullanılabileceği anlamına gelir. - Önyükleme sırasında önyükleme düzeyi artırılırsa HKDF işlevi kullanılarak K0'dan bu önyükleme düzeyi için yeni bir anahtar oluşturulabilir:
Ki+i=HKDF(Ki, "some_fixed_string"). Örneğin, önyükleme seviyesi 0'dan önyükleme seviyesi 10'a geçerseniz K10'u K0'dan türetmek için HKDF 10 kez çağrılır. Önyükleme düzeyi değiştiğinde önceki önyükleme düzeyinin anahtarı bellekten silinir ve önceki önyükleme düzeyleriyle ilişkili anahtarlar artık kullanılamaz.
K0 anahtarı bir
MAX_USES_PER_BOOT=1anahtarıdır. Bu nedenle, en az bir başlatma seviyesi geçişi (nihai başlatma seviyesine) her zaman gerçekleştiğinden bu anahtarı daha sonra başlatma işleminde kullanmak da mümkün değildir.
odsign gibi bir Keystore istemcisi, önyükleme düzeyinde i bir anahtar oluşturulmasını istediğinde blob'u Ki anahtarıyla şifrelenir. Ki, i önyükleme seviyesinden sonra kullanılamadığından bu anahtar, sonraki önyükleme aşamalarında oluşturulamaz veya şifresi çözülemez.
Keymaster 4.1 ve KeyMint 1.0 uygulaması
Keymaster 4.1 ve KeyMint 1.0 uygulamaları, Keymaster 4.0 uygulamasıyla büyük ölçüde aynıdır. Temel fark, K0'ın MAX_USES_PER_BOOT anahtarı değil, Keymaster 4.1'de kullanıma sunulan bir EARLY_BOOT_ONLY anahtarı olmasıdır. EARLY_BOOT_ONLY anahtarı yalnızca önyüklemenin ilk aşamalarında, güvenilmeyen kod çalışmadığı zaman kullanılabilir. Bu, ek bir koruma düzeyi sağlar: Keymaster 4.0 uygulamasında, dosya sisteminin ve SELinux'un güvenliğini ihlal eden bir saldırgan, Keystore veritabanını değiştirerek yapay nesneleri imzalamak için kendi MAX_USES_PER_BOOT=1 anahtarını oluşturabilir. Keymaster 4.1 ve KeyMint 1.0 uygulamalarında bu tür bir saldırı mümkün değildir. Bunun nedeni, EARLY_BOOT_ONLY anahtarlarının yalnızca erken başlatma sırasında oluşturulabilmesidir.
Güvenilir imza anahtarlarının ortak bileşeni
odsign, imzalama anahtarının ortak anahtar bileşenini anahtar deposundan alır.
Ancak Keystore, ilgili özel anahtarı barındıran TEE/SE'den bu ortak anahtarı almaz. Bunun yerine, ortak anahtarı kendi disk üzerindeki veritabanından alır. Bu, dosya sistemini tehlikeye atan bir saldırganın, kontrolü altındaki bir ortak/özel anahtar çiftinin parçası olan bir ortak anahtar içerecek şekilde anahtar deposu veritabanını değiştirebileceği anlamına gelir.
Bu saldırıyı önlemek için odsign, imza anahtarıyla aynı önyükleme düzeyine sahip ek bir HMAC anahtarı oluşturur. Ardından, imza anahtarı oluşturulurken odsign, ortak anahtarın imzasını oluşturmak için bu HMAC anahtarını kullanır ve bunu diske kaydeder. Sonraki başlatma işlemlerinde, imzalama anahtarının ortak anahtarı alınırken diskteki imzanın, alınan ortak anahtarın imzasıyla eşleştiğini doğrulamak için HMAC anahtarı kullanılır. Eşleşme varsa ortak anahtar güvenilirdir. Çünkü HMAC anahtarı yalnızca erken başlatma seviyelerinde kullanılabilir ve bu nedenle saldırgan tarafından oluşturulamaz.