dm-verity'yi uygulama

Android 4.4 ve üzeri, 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, root ayrıcalıklarına sahip olabilecek ve cihazların güvenliğini tehlikeye atabilecek kalıcı rootkit'lerin önlenmesine yardımcı olur. Bu özellik, Android kullanıcılarının, bir cihazı başlatırken, cihazın en son kullanıldığı zamanki durumunda 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 başka şekilde 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öylemesine" olanak tanır.

Dm-verity özelliği, dosya sisteminin temel depolama katmanı olan blok cihazına bakmanıza ve beklenen yapılandırmayla eşleşip eşleşmediğini belirlemenize olanak tanır. Bunu bir kriptografik karma ağacı kullanarak yapar. Her blok için (tipik olarak 4k) bir SHA256 karma değeri vardır.

Karma değerleri bir sayfa ağacında saklandığından, ağacın geri kalanını doğrulamak için yalnızca en üst düzey "kök" karma değerine güvenilmelidir. Bloklardan herhangi birini değiştirme yeteneği, kriptografik karmanın kırılmasına eşdeğer olacaktır. Bu yapının bir tasviri için aşağıdaki şemaya bakın.

dm-verity-hash-tablosu

Şekil 1. dm-verity karma 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 cihazı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 bulunur. Dolayısıyla, 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. Cihaz fabrikadan çıktıktan sonra bu anahtar değiştirilemez.

Üreticiler bu anahtarı birinci düzey önyükleyicideki imzayı doğrulamak için kullanır; bu da sonraki düzeylerdeki imzayı, uygulama önyükleyicisini ve sonunda çekirdeği doğrular. Doğrulanmış önyüklemeden yararlanmak isteyen her üreticinin, çekirdeğin bütünlüğünü doğrulamak için bir yöntemi olması gerekir. Çekirdeğin doğrulandığını varsayarsak, çekirdek bir blok aygıtına bakabilir ve onu monte edildiğinde doğrulayabilir.

Bir blok cihazını doğrulamanın bir yolu, içeriklerini doğrudan hashlemek ve bunları kayıtlı bir değerle karşılaştırmaktır. Ancak blok cihazın tamamını doğrulamaya çalışmak uzun bir süre alabilir ve cihazın gücünün çoğunu tüketebilir. Cihazların başlatılması uzun sürüyor ve kullanımdan önce önemli ölçüde tükeniyordu.

Bunun yerine dm-verity, blokları tek tek ve yalnızca her birine erişildiğinde doğrular. Belleğe okunduğunda blok paralel olarak karmalanır. Karma daha sonra ağaçta doğrulanır. Bloğun okunması ç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ı üretir. 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, sonuç verileri olmadan ilerlemeyi seçebilir. Ancak uygulama veri olmadan devam edemezse başarısız olur.

İleri hata düzeltme

Android 7.0 ve üzeri, 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 Zorunlu Doğrulanmış Önyükleme .

Uygulama

Özet

  1. Bir ext4 sistem görüntüsü oluşturun.
  2. Bu görüntü için bir karma ağacı oluşturun .
  3. Bu karma ağacı için bir dm-verity tablosu oluşturun .
  4. Bir tablo imzası oluşturmak için bu dm-verity tablosunu imzalayın .
  5. Tablo imzasını ve dm-verity tablosunu verity meta verilerine paketleyin .
  6. Sistem görüntüsünü, gerçeklik 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ış Önyükleme sayfasına bakın.

Hash ağacının oluşturulması

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şturacaktır. Alternatif olarak uyumlu olanı burada 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 birine bir SHA256 karması atanan 4k bloklara bölünür. Katman 1, yalnızca bu SHA256 karmalarının 4k bloklar halinde birleştirilmesiyle oluşturulur ve sonuçta çok daha küçük bir görüntü elde edilir. Katman 2, Katman 1'in SHA256 karmalarıyla aynı şekilde oluşturulur.

Bu, önceki katmanın SHA256 karmaları tek bir bloğa sığıncaya kadar yapılır. Bu bloğun SHA256'sını aldığınızda, ağacın kök karmasını elde edersiniz.

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 karma ağaçlarının boyutu genellikle 30 MB'ın altında olmak üzere küçük olma eğilimindedir.

Bir katmanda, önceki katmanın karmaları tarafından doğal olarak tamamen doldurulmamış bir bloğunuz varsa, beklenen 4k'yi elde etmek için onu sıfırlarla doldurmanız gerekir. Bu, karma 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, katman 2 karmalarını katman 1'in karmalarına, katman 3 karmalarını katman 2'nin karmalarına vb. birleştirin. Bunların hepsini diske yazın. Bunun kök karmasının 0. katmanına referans vermediğini unutmayın.

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

  1. Rastgele bir tuz seçin (onaltılık kodlama).
  2. Sistem görüntünüzü 4k bloklara ayırın.
  3. Her blok için (tuzlu) SHA256 karma değerini alın.
  4. Bir düzey oluşturmak için bu karmaları birleştirin
  5. Seviyeyi 0'larla 4k blok sınırına kadar doldurun.
  6. Seviyeyi karma ağacınıza birleştirin.
  7. Yalnızca tek bir karma elde edene kadar önceki düzeyi bir sonraki düzey 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 tuzunuz, dm-verity haritalama tablonuzun oluşturulması sırasında kullanılır.

DM-verity eşleme tablosunu oluşturma

Çekirdek için blok aygıtını (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. Tablo aynı zamanda blokların boyutunu ve karma ağacının başlangıç ​​konumu olan hash_start'ı (özellikle görüntünün başlangıcından itibaren blok numarasını) tanımlar.

Doğruluk hedefi eşleme tablosu alanlarının ayrıntılı açıklaması için cryptsetup'a bakın.

DM-verity tablosunun imzalanması

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

Bölümü bu imza ve tuş birleşimiyle doğrulamak için:

  1. /verity_key konumundaki /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 tanımlayın.
  2. İlgili girişin fstab'ında, fs_mgr işaretlerine verify ekleyin.

Tablo imzasını meta verilere paketleme

Tablo imzasını ve dm-verity tablosunu verity meta verilerine paketleyin. Meta veri bloğunun tamamı, ikinci tür bir imza eklemek veya bazı sıralamaları değiştirmek gibi genişletilebilecek şekilde sürümlendirilmiştir.

Bir akıl sağlığı kontrolü olarak, tablonun tanımlanmasına yardımcı olan her bir tablo meta verisi kümesiyle sihirli bir sayı ilişkilendirilir. Uzunluk ext4 sistem görüntü başlığına dahil edildiğinden, bu, verinin içeriğini bilmeden meta veriyi aramanın bir yolunu sağlar.

Bu, doğrulanmamış bir bölümü doğrulamayı seçmediğinizden emin olmanızı sağlar. Eğer öyleyse, bu sihirli sayının yokluğu doğrulama işlemini 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 şemada doğruluk meta verilerinin dökümü gösterilmektedir:

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

Ve bu tablo bu meta veri alanlarını açıklamaktadır.

Tablo 1. Verity 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 versiyonlamak için kullanılır 4 bayt şu anda 0
imza PKCS1.5 dolgulu formdaki tablonun imzası 256 bayt
masa uzunluğu dm-verity tablosunun bayt cinsinden uzunluğu 4 bayt
masa daha önce açıklanan dm-verity tablosu tablo uzunluğu baytları
dolgu malzemesi bu yapı 0 dolgulu ila 32k uzunluğundadır 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ını deneyin.