Android 12'den itibaren Android Çalışma Zamanı (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ıları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şene sahiptir:
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ı gerekirseodrefresh
bunları oluşturup saklar.odsign
, Android platformunun bir parçası olan bir ikili programdır./data
bölümü bağlandıktan hemen sonra, erken başlatma sırasında çalışır. Temel sorumluluğu,odrefresh
işlevini çağırarak herhangi bir yapının oluşturulması veya güncellenmesi gerekip gerekmediğini kontrol etmektir.odrefresh
tarafı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,odsign
tarafından daha önce hesaplanan özetlerle eşleştiğini doğrular. Bu, yapay nesnelerin değiştirilmediğini garanti eder.
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 hale 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
, 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ına gerek kalmaz. Bunun yerine, yapay ürün verileri, fs-verity tarafından kullanıldıkça blok bazında 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 her iki durumda da özetler 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 imza anahtarıyla imzalanır. Özellikle anahtar yalnızca güvenilir kodun çalıştığı erken başlatma sırasında oluşturulup kullanılabilir. Ayrıntılar için Güvenilir imzalama anahtarları başlıklı makaleyi inceleyin.
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ını doğrular. İ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.info
uygulamasının kendi sürümlerini imzalamak için imzalama anahtarımızı kullanmasını ne engeller? - Saldırganların kendi imzalama anahtarlarını oluşturup
odsign.info
uygulaması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 ayırır ve anahtarın oluşturulması ile 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
konumundan bir sistem özelliği ayarlayarak başlatma düzeyini artırabilirsiniz. Örneğin, aşağıdaki kod, başlatma düzeyini 10 olarak ayarlar:
setprop keystore.boot_level 10
Keystore istemcileri, 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 ile ilişkili 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ı bulana kadar önyükleme düzeyinin 30'un üzerine çıkması 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
odsign
bunu reddeder.
Keystore, önyükleme düzeyinin düzgün şekilde uygulanması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 ele alır:
- Keystore, ilk başlatmada
MAX_USES_PER_BOOT
etiketi1
olarak 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 söz konusu ö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.
Anahtar K0,
MAX_USES_PER_BOOT=1
anahtarıdır. Bu nedenle, en az bir başlatma seviyesi geçişi (son başlatma seviyesine) her zaman gerçekleştiğinden bu anahtarın daha sonra başlatma işleminde kullanılması 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 herkese açık 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, anahtar deposu veritabanını kendi kontrolü altındaki bir ortak/özel anahtar çiftinin parçası olan bir ortak anahtar içerecek şekilde 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.