Android 4.4 ve üstü, blok cihazların şeffaf bütünlük kontrolünü sağlayan isteğe bağlı cihaz eşleyici-verity (dm-verity) çekirdek özelliği aracılığıyla Doğrulanmış Önyüklemeyi destekler. dm-verity, kök ayrıcalıklarına sahip olabilen ve aygıtları tehlikeye atabilen kalıcı kök kullanıcı setlerini önlemeye yardımcı olur. Bu özellik, Android kullanıcılarının bir cihazı başlatırken en son kullanıldığı durumda olduğundan emin olmalarına yardımcı olur.
Kök ayrıcalıklarına sahip Potansiyel Olarak Zararlı Uygulamalar (PHA'lar), algılama programlarından gizlenebilir ve aksi takdirde kendilerini maskeleyebilir. Köklendirme yazılımı bunu yapabilir çünkü genellikle dedektörlerden daha ayrıcalıklıdır ve yazılımın algılama programlarına "yalan söylemesini" sağlar.
dm-verity özelliği, dosya sisteminin temel depolama katmanı olan bir blok aygıtına bakmanıza ve beklenen yapılandırmayla eşleşip eşleşmediğini belirlemenize olanak tanır. Bunu bir kriptografik hash ağacı kullanarak yapar. Her blok için (tipik olarak 4k), bir SHA256 karması vardır.
Karma değerleri bir sayfa ağacında depolandığından, ağacın geri kalanını doğrulamak için yalnızca üst düzey "kök" karma değerine güvenilmelidir. Bloklardan herhangi birini değiştirme yeteneği, kriptografik karmayı kırmaya eşdeğer olacaktır. Bu yapının bir tasviri için aşağıdaki şemaya bakın.

Şekil 1. dm-verity hash tablosu
Önyükleme bölümünde, aygıt üreticisi tarafından harici olarak doğrulanması gereken bir ortak anahtar bulunur. Bu anahtar, söz konusu karma için imzayı doğrulamak ve aygıtın sistem bölümünün korunduğunu ve değiştirilmediğini doğrulamak için kullanılır.
Operasyon
dm-verity koruması çekirdekte yaşar. Bu nedenle, köklendirme yazılımı, çekirdek ortaya çıkmadan önce sistemi tehlikeye atarsa, bu erişimi koruyacaktır. Bu riski azaltmak için çoğu üretici, cihaza yazılan bir anahtarı kullanarak çekirdeği doğrular. Bu tuş, cihaz fabrikadan çıktıktan sonra değiştirilemez.
Üreticiler bu anahtarı birinci düzey önyükleyicideki imzayı doğrulamak için kullanırlar, bu da sonraki düzeylerde, uygulama önyükleyicisinde ve nihayetinde çekirdekte imzayı doğrular. Doğrulanmış önyüklemeden yararlanmak isteyen her üretici, çekirdeğin bütünlüğünü doğrulamak için bir yönteme sahip olmalıdır. Çekirdeğin doğrulandığını varsayarsak, çekirdek bir blok aygıtına bakabilir ve takılıyken doğrulayabilir.
Bir blok cihazını doğrulamanın bir yolu, içeriğini doğrudan hash etmek ve bunları saklanan bir değerle karşılaştırmaktır. Ancak, tüm blok cihazını doğrulamaya çalışmak uzun bir süre alabilir ve cihazın gücünün çoğunu tüketebilir. Cihazların önyüklenmesi uzun süreler alacak ve ardından kullanımdan önce önemli ölçüde boşaltılacaktır.
Bunun yerine, dm-verity blokları tek tek ve yalnızca her birine erişildiğinde doğrular. Belleğe okunduğunda, blok paralel olarak özetlenir. Karma daha sonra ağaçta doğrulanır. Ve bloğu okumak çok pahalı bir işlem olduğundan, bu blok düzeyinde doğrulamanın getirdiği gecikme nispeten nominaldir.
Doğrulama başarısız olursa, cihaz bloğun okunamadığını belirten bir G/Ç hatası oluşturur. Beklendiği gibi dosya sistemi bozulmuş gibi görünecektir.
Uygulamalar, örneğin bu sonuçların uygulamanın birincil işlevi için gerekli olmadığı durumlarda olduğu gibi, elde edilen veriler olmadan devam etmeyi seçebilir. Ancak uygulama veriler olmadan devam edemezse başarısız olur.
İleri hata düzeltme
Android 7.0 ve üstü, ileri hata düzeltme (FEC) ile dm-verity sağlamlığını artırır. AOSP uygulaması, ortak Reed-Solomon hata düzeltme koduyla başlar ve alan yükünü azaltmak ve kurtarılabilecek bozuk blokların sayısını artırmak için serpiştirme adı verilen bir teknik uygular. FEC hakkında daha fazla ayrıntı için, bkz. Hata Düzeltmeli Kesinlikle Zorlanan Doğrulanmış Önyükleme .uygulama
Özet
- Bir ext4 sistem görüntüsü oluşturun.
- Bu görüntü için bir karma ağacı oluşturun .
- Bu hash ağacı için bir dm-verity tablosu oluşturun.
- Bir tablo imzası oluşturmak için bu dm-verity tablosunu imzalayın .
- Tablo imzasını ve dm-verity tablosunu doğru meta verilerine paketleyin.
- Sistem görüntüsünü, doğruluk meta verilerini ve karma ağacını birleştirin.
Karma ağacının ve dm-verity tablosunun ayrıntılı açıklaması içinChromium Projeleri - Doğrulanmış Önyükleme'ye bakın.
Hash ağacının oluşturulması
Girişte açıklandığı gibi, hash ağacı dm-verity'nin ayrılmaz bir parçasıdır. cryptsetup aracı sizin için bir hash ağacı oluşturacaktır. Alternatif olarak, burada uyumlu bir tane tanımlanır:
<your block device name> <your block device name> <block size> <block size> <image size in blocks> <image size in blocks + 8> <root hash> <salt>
Karmayı oluşturmak için, sistem görüntüsü katman 0'da her biri bir SHA256 karma değeri atanan 4k bloklara bölünür. Katman 1, yalnızca bu SHA256 karmalarının 4k bloklara birleştirilmesiyle oluşturulur ve çok daha küçük bir görüntü elde edilir. Katman 2, Katman 1'in SHA256 karmaları ile aynı şekilde oluşturulur.
Bu, önceki katmanın SHA256 karmaları tek bir bloğa sığana kadar yapılır. Bu bloğun SHA256'sını aldığınızda, ağacın kök karmasına sahip olursunuz.
Karma ağacının boyutu (ve karşılık gelen disk alanı kullanımı), doğrulanan bölümün boyutuna göre değişir. Uygulamada, hash ağaçlarının boyutu genellikle 30 MB'tan daha küçük olan küçük olma eğilimindedir.
Bir katmanda, önceki katmanın hash'leri tarafından doğal olarak tamamen doldurulmamış bir bloğunuz varsa, beklenen 4k'yi elde etmek için onu sıfırlarla doldurmalısınız. Bu, hash ağacının kaldırılmadığını ve bunun yerine boş verilerle tamamlandığını bilmenizi sağlar.
Karma ağacını oluşturmak için, 2. katman karmalarını katman 1 için olanlarla, katman 3'ü karmaları katman 2'ninkilerle birleştirin ve bu şekilde devam edin. Bunların hepsini diske yazın. Bunun kök karmanın 0 katmanına başvurmadığını unutmayın.
Özetlemek gerekirse, karma ağacı oluşturmak için genel algoritma aşağıdaki gibidir:
- Rastgele bir tuz seçin (onaltılık kodlama).
- Sistem görüntünüzü 4k bloklara ayırın.
- Her blok için (tuzlanmış) SHA256 karmasını alın.
- Bir seviye oluşturmak için bu karmaları birleştirin
- Seviyeyi 0'larla 4k blok sınırına getirin.
- Seviyeyi hash ağacınızla birleştirin.
- Yalnızca tek bir karma elde edene kadar önceki seviyeyi bir sonraki için kaynak olarak kullanarak 2-6 arasındaki adımları tekrarlayın.
Bunun sonucu, kök karmanız olan tek bir karmadır. Bu ve sizin tuzunuz, dm-verity haritalama tablonuzun yapımında kullanılır.
dm-verity eşleme tablosunu oluşturma
Çekirdek için blok aygıtı (veya hedefi) ve karma ağacının (aynı değerde olan) konumunu tanımlayan dm-verity eşleme tablosunu oluşturun. Bu eşleme fstab
oluşturma ve önyükleme için kullanılır. Tablo ayrıca blokların boyutunu ve hash_start'ı, hash ağacının başlangıç konumunu (özellikle, görüntünün başlangıcından itibaren blok numarası) tanımlar.
Doğruluk hedefi eşleme tablosu alanlarının ayrıntılı açıklaması için cryptsetup'a bakın.
dm-verity tablosunu imzalama
Bir tablo imzası oluşturmak için dm-verity tablosunu imzalayın. Bir bölümü doğrularken, önce tablo imzası doğrulanır. Bu, sabit bir konumdaki önyükleme görüntünüzdeki bir tuşa karşı yapılır. Anahtarlar, genellikle sabit bir konumdaki cihazlara otomatik olarak dahil edilmek üzere üreticilerin yapı sistemlerine dahil edilir.
Bu imza ve tuş kombinasyonu ile bölümü doğrulamak için:
-
/verity_key
/boot
bölümüne libmincrypt uyumlu biçimde bir RSA-2048 anahtarı ekleyin. Karma ağacı doğrulamak için kullanılan anahtarın konumunu belirleyin. - İlgili girişin fstab'ında
fs_mgr
bayraklarınaverify
ekleyin.
Tablo imzasını meta verilere paketleme
Tablo imzasını ve dm-verity tablosunu doğru meta verilerine paketleyin. Tüm meta veri bloğu, ikinci bir imza türü eklemek veya bazı sıralamaları değiştirmek gibi genişletilebilecek şekilde sürümlendirilir.
Akıl sağlığı kontrolü olarak, tablonun tanımlanmasına yardımcı olan her bir tablo meta verisi grubuyla bir sihirli sayı ilişkilendirilir. Uzunluk, ext4 sistem görüntü başlığına dahil edildiğinden, bu, verilerin içeriğini bilmeden meta verileri aramak için bir yol sağlar.
Bu, doğrulanmamış bir bölümü doğrulamayı seçmediğinizden emin olur. Eğer öyleyse, bu sihirli sayının olmaması doğrulama sürecini durduracaktır. Bu sayı şuna benzer:
0xb001b001
Hex cinsinden bayt değerleri şunlardır:
- ilk bayt = b0
- ikinci bayt = 01
- üçüncü bayt = b0
- dördüncü bayt = 01
Aşağıdaki şema, doğruluk meta verilerinin dökümünü göstermektedir:
<magic number>|<version>|<signature>|<table length>|<table>|<padding> \-------------------------------------------------------------------/ \----------------------------------------------------------/ | | | | 32K block content
Ve bu tablo bu meta veri alanlarını açıklar.
Tablo 1. Doğruluk meta veri alanları
Alan | Amaç | Boyut | Değer |
---|---|---|---|
sihirli sayı | fs_mgr tarafından akıl sağlığı kontrolü olarak kullanılır | 4 bayt | 0xb001b001 |
versiyon | meta veri bloğunu sürümlendirmek için kullanılır | 4 bayt | şu anda 0 |
imza | tablonun imzası PKCS1.5 dolgulu formda | 256 bayt | |
masa uzunluğu | bayt cinsinden dm-verity tablosunun uzunluğu | 4 bayt | |
masa | daha önce açıklanan dm-verity tablosu | tablo uzunluğu baytları | |
dolgu malzemesi | bu yapı 0-32k uzunluğa kadar dolguludur | 0 |
dm-verity'yi optimize etme
dm-verity'den en iyi performansı elde etmek için şunları yapmalısınız:
- Çekirdekte, ARMv7 için NEON SHA-2'yi ve ARMv8 için SHA-2 uzantılarını açın.
- Cihazınız için en iyi yapılandırmayı bulmak için farklı ileri okuma ve prefetch_cluster ayarlarıyla denemeler yapın.