Dm-verity uygulayın

Android 4.4 ve sonraki sürümler, blok cihazların şeffaf bütünlük kontrolünü sağlayan isteğe bağlı device-mapper-verity (dm-verity) çekirdek özelliği aracılığıyla Doğrulanmış Başlatma'yı destekler. dm-verity, root ayrıcalıklarını koruyabilen ve cihazların güvenliğini ihlal edebilecek kalıcı rootkit'lerin önlenmesine yardımcı olur. Bu özellik, Android kullanıcılarının cihazı açtıklarında cihazın en son kullanıldığındaki durumda olduğundan emin olmalarını sağlar.

Kök ayrıcalıklarına sahip Potansiyel Olarak Zararlı Uygulamalar (PHA'lar), tespit programlarından gizlenebilir ve kendilerini başka şekilde maskeleyebilir. Köklendirme yazılımı, genellikle algılayıcılardan daha ayrıcalıklı olduğu için bunu yapabilir. Bu da yazılımın algılama programlarına "yalan söylemesine" olanak tanır.

dm-verity özelliği, dosya sisteminin temel depolama katmanı olan bir blok cihaza bakmanızı ve beklenen yapılandırmayla eşleşip eşleşmediğini belirlemenizi sağlar. Bunu, şifreleme karma değeri ağacı kullanarak yapar. Her blok (genellikle 4k) için bir SHA256 karması vardır.

Karma oluşturma 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 oluşturma değerine güvenilmelidir. Bloklardan herhangi birini değiştirmek, kriptografik karmanın kırılmasıyla eşdeğerdir. Bu yapının tasviri için aşağıdaki şemaya bakın.

dm-verity-hash-table

Şekil 1. dm-verity karma tablosu

Başlatma bölümüne, cihaz üreticisi tarafından harici olarak doğrulanması gereken bir ortak anahtar eklenir. Bu anahtar, ilgili karma oluşturma işleminin imzasını doğrulamak ve cihazın sistem bölümünün korunduğunu ve değiştirilmediğini onaylamak için kullanılır.

İşlem

dm-verity koruması çekirdekte bulunur. Bu nedenle, köklendirme yazılımı çekirdek başlatılmadan önce sistemi tehlikeye atarsa bu erişimi korur. Çoğu üretici, bu riski azaltmak için cihaza yerleştirilmiş bir anahtar kullanarak çekirdeği doğrular. Bu anahtar, cihaz fabrikadan çıktıktan sonra değiştirilemez.

Üreticiler bu anahtarı kullanarak ilk seviye önyükleyicideki imzayı doğrular. Bu da sonraki seviyelerdeki imzayı (uygulama önyükleyici ve nihayetinde çekirdek) doğrular. Doğrulanmış başlatma özelliğinden yararlanmak isteyen her üreticinin, çekirdeğin bütünlüğünü doğrulamak için bir yöntemi olmalıdır. Çekirdek doğrulanmışsa bir blok cihazı inceleyebilir ve monte edildiği sırada doğrulayabilir.

Bir blok cihazı doğrulamanın bir yolu, içeriğini doğrudan karma oluşturarak depolanan bir değerle karşılaştırmaktır. Ancak bir blok cihazın tamamını doğrulamaya çalışmak uzun sürebilir ve cihazın gücünün büyük bir kısmını tüketebilir. Cihazların başlatılması uzun sürer ve daha sonra kullanımdan önce pilleri önemli ölçüde tükenir.

Bunun yerine dm-verity, blokları tek tek ve yalnızca her birine erişildiğinde doğrular. Belleğe okunduğunda blok paralel olarak karma oluşturma işlemine tabi tutulur. Karma oluşturma işlemi daha sonra ağaçta doğrulanır. Ayrıca, bloğu okumak oldukça pahalı bir işlem olduğundan bu blok düzeyinde doğrulamanın neden olduğu gecikme nispeten önemsizdir.

Doğrulama başarısız olursa cihaz, bloğun okunamadığını belirten bir G/Ç hatası oluşturur. Beklenen gibi, dosya sisteminin bozulduğu görülüyor.

Uygulamalar, elde edilen veriler olmadan devam etmeyi seçebilir (ör. bu sonuçlar uygulamanın birincil işlevi için gerekli olmadığında). Ancak uygulama, veriler olmadan devam edemezse başarısız olur.

İleriye doğru hata düzeltme

Android 7.0 ve sonraki sürümler, ileri hata düzeltmesi (FEC) ile dm-verity'nin sağlamlığını artırır. AOSP uygulaması, yaygın Reed-Solomon hata düzeltme koduyla başlar ve alan yükü azaltmak ve kurtarılabilen bozuk blok sayısını artırmak için ardışık düzenleme adı verilen bir teknik uygular. FEC hakkında daha fazla bilgi için Hata Düzeltme ile Sıkı Denetimli Doğrulanmış Başlatma başlıklı makaleyi inceleyin.

Uygulama

Özet

  1. ext4 sistem görüntüsü oluşturun.
  2. İlgili resim için karma ağacı oluşturun.
  3. Söz konusu karma ağacı için dm-verity tablosu oluşturun.
  4. Tablo imzası oluşturmak için bu dm-verity tablosunu imzalayın.
  5. Tablo imzasını ve dm-verity tablosunu Verity meta verilerine bağlayın.
  6. Sistem görüntüsünü, doğruluk meta verilerini ve karma ağacını birleştirin.

Karma ağacı ve dm-verity tablosunun ayrıntılı açıklaması için Chromium Projeleri - Doğrulanmış Başlatma başlıklı makaleyi inceleyin.

Karma ağacı oluşturma

Giriş bölümünde açıklandığı gibi, karma ağacı dm-verity'nin ayrılmaz bir parçasıdır. cryptsetup aracı sizin için bir karma ağacı oluşturur. Alternatif olarak, uyumlu bir sürüm burada tanımlanmıştı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>

Karma oluşturmak için sistem görüntüsü 0. katmanda 4K bloklara bölünür ve her birine bir SHA256 karması atanır. 1. katman, yalnızca bu SHA256 karmalarının 4K bloklar halinde birleştirilmesiyle oluşturulur. Bu da çok daha küçük bir resim elde edilmesini sağlar. 2. katman, 1. katmanın SHA256 karmalarıyla aynı şekilde oluşturulur.

Bu işlem, önceki katmanın SHA256 karma değerleri tek bir bloğa sığana kadar devam eder. Bu bloğun SHA256 değerini 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ğrulanmış bölümün boyutuna göre değişir. Uygulamada karma ağaçlarının boyutu genellikle küçüktür (genellikle 30 MB'tan az).

Bir katmanda, önceki katmanın karma oluşturma işlemleriyle doğal olarak tamamen doldurulmamış bir blok varsa beklenen 4K'ya ulaşmak için bu bloğu sıfırlarla doldurmanız gerekir. Bu sayede, karma ağacının kaldırılmadığını ve bunun yerine boş verilerle doldurulduğunu anlayabilirsiniz.

Karma oluşturma ağacını oluşturmak için 2. katman karmalarını 1. katman karmalarıyla, 3. katman karmalarını 2. katman karmalarıyla ve bu şekilde devam ederek birleştirin. Tüm bunları diske yazın. Bunun, kök karmasının 0. katmanına referans vermediğini unutmayın.

Özetlemek gerekirse karma ağacı oluşturmaya yönelik genel algoritma aşağıdaki gibidir:

  1. Rastgele bir tuz (on altılık kodlama) seçin.
  2. Sistem resminizi 4K bloklara ayırın.
  3. Her blok için (tuzlanmış) SHA256 karmasını alın.
  4. Bir seviye oluşturmak için bu karma oluşturma işlemlerini birleştirin
  5. Seviyeyi 4k blok sınırına kadar 0 ile doldurun.
  6. Seviyeyi karma ağacınızla birleştirin.
  7. Yalnızca tek bir karma oluşturana kadar önceki seviyeyi sonraki seviyenin kaynağı olarak kullanarak 2-6 arasındaki adımları tekrarlayın.

Bunun sonucunda tek bir karma oluşturma işlemi gerçekleşir. Bu karma, kök karmanızdır. Bu değer ve tuzunuz, dm-verity eşleme tablonuzun oluşturulması sırasında kullanılır.

dm-verity eşleme tablosunu oluşturma

Çekirdek için blok cihazı (veya hedefi) ve karma ağacının konumunu (aynı değerdir) tanımlayan dm-verity eşleme tablosunu oluşturun. Bu eşleme, fstab oluşturma ve önyükleme için kullanılır. Tabloda, blokların boyutu ve karma ağacının başlangıç konumu (özellikle, resmin başındaki blok numarası) olan hash_start da tanımlanır.

Verity hedef eşleme tablosu alanlarının ayrıntılı açıklaması için cryptsetup bölümüne bakın.

dm-verity tablosunu imzalama

Tablo imzası oluşturmak için dm-verity tablosunu imzalayın. Bir bölüm doğrulanırken önce tablo imzası doğrulanır. Bu işlem, önyükleme görüntünüzde sabit bir konumdaki bir anahtara göre yapılır. Anahtarlar genellikle sabit bir konumdaki cihazlara otomatik olarak dahil edilmek için üreticilerin derleme sistemlerine dahil edilir.

Bu imza ve anahtar kombinasyonuyla bölümü doğrulamak için:

  1. /verity_key adresindeki /boot bölümüne libmincrypt uyumlu biçimde bir RSA-2048 anahtarı ekleyin. Karma ağacını doğrulamak için kullanılan anahtarın konumunu belirleyin.
  2. İlgili girişin fstab dosyasında fs_mgr işaretlerine verify ekleyin.

Tablo imzasını meta verilerle bir araya getirme

Tablo imzasını ve dm-verity tablosunu verity meta verilerine bağlayın. Meta veri bloğunun tamamı, ikinci bir imza türü eklemek veya bazı sıralamaları değiştirmek gibi genişletilebilir olması için sürümlendirilir.

Tablonun tanımlanmasına yardımcı olan her tablo meta verisi grubuyla bir sihirli sayı ilişkilendirilir. Uzunluk, ext4 sistem resmi başlığına dahil edildiğinden, verilerin içeriğini bilmeden meta verileri aramanın bir yolu sağlanır.

Bu sayede, doğrulanmamış bir bölümü doğrulamayı seçmemiş olursunuz. Bu durumda, bu sihirli numaranın olmaması doğrulama sürecini durdurur. Bu sayı 0xb001b001 değerine benzer.

Onaltılık sistemdeki bayt değerleri şunlardır:

  • ilk bayt = b0
  • ikinci bayt = 01
  • üçüncü bayt = b0
  • dördüncü bayt = 01

Aşağıdaki şemada, Verity meta verilerinin dökümü gösterilmektedir:

<magic number>|<version>|<signature>|<table length>|<table>|<padding>
\-------------------------------------------------------------------/
\----------------------------------------------------------/   |
                            |                                  |
                            |                                 32K
                       block content

Bu tabloda söz konusu meta veri alanları açıklanmaktadır.

Tablo 1. Meta veri alanlarını doğrulama

Alan Amaç Boyut Değer
sihirli numara fs_mgr tarafından doğrulama kontrolü olarak kullanılır 4 bayt 0xb001b001
sürüm Meta veri bloğunun sürümünü belirlemek için kullanılır. 4 bayt şu anda 0
signature PKCS1.5 dolgulu biçimde tablonun imzası 256 bayt
tablo uzunluğu dm-verity tablosunun bayt cinsinden uzunluğu 4 bayt
masa Daha önce açıklanan dm-verity tablosu tablo uzunluğu baytları
padding Bu yapı, 32 bin uzunluğa kadar 0 ile doldurulur. 0

dm-verity'yi optimize etme

dm-verity'den en iyi performansı elde etmek için:

  • Çekirdekte, ARMv7 için NEON SHA-2 ve ARMv8 için SHA-2 uzantılarını etkinleştirin.
  • Cihazınız için en iyi yapılandırmayı bulmak üzere farklı önceden okuma ve prefetch_cluster ayarlarıyla denemeler yapın.