Çoğu disk ve dosya şifreleme yazılımı gibi, Android'in depolama şifrelemesi de geleneksel olarak şifrelemenin gerçekleştirilebilmesi için sistem belleğinde bulunan ham şifreleme anahtarlarına dayanır. Şifreleme, yazılım yerine özel donanım tarafından gerçekleştirilse bile, yazılımın genellikle ham şifreleme anahtarlarını yönetmesi gerekir.
Bu geleneksel olarak bir sorun olarak görülmez çünkü anahtarlar, depolama şifrelemesinin korumayı amaçladığı ana saldırı türü olan çevrimdışı saldırı sırasında mevcut olmayacaktır. Bununla birlikte, soğuk başlatma saldırıları ve bir saldırganın cihazdan tamamen ödün vermeden sistem belleğini sızdırabileceği çevrimiçi saldırılar gibi diğer saldırı türlerine karşı artırılmış koruma sağlama isteği vardır.
Bu sorunu çözmek için Android 11, donanım desteğinin mevcut olduğu donanımla sarılmış anahtarlar desteğini sundu. Donanımla sarılmış anahtarlar, yalnızca özel donanım tarafından ham biçimde bilinen depolama anahtarlarıdır; yazılım bu anahtarları yalnızca sarılmış (şifrelenmiş) biçimde görür ve onlarla çalışır. Bu donanım, depolama anahtarlarını oluşturup içe aktarabilmeli, depolama anahtarlarını geçici ve uzun vadeli formlarda paketleyebilmeli, alt anahtarları türetebilmeli, bir alt anahtarı doğrudan satır içi bir kripto motoruna programlayabilmeli ve yazılıma ayrı bir alt anahtar döndürebilmelidir.
Not : Satır içi kripto motoru (veya satır içi şifreleme donanımı ), depolama aygıtına giderken/aygıttan ayrılırken verileri şifreleyen/şifresini çözen donanımı ifade eder. Genellikle bu, ilgili JEDEC spesifikasyonu tarafından tanımlanan kripto uzantılarını uygulayan bir UFS veya eMMC ana bilgisayar denetleyicisidir.
Tasarım
Bu bölümde, hangi donanım desteğinin gerekli olduğu da dahil olmak üzere, donanımla sarılmış tuşlar özelliğinin tasarımı sunulmaktadır. Bu tartışma dosya tabanlı şifrelemeye (FBE) odaklanmaktadır, ancak çözüm meta veri şifrelemesi için de geçerlidir.
Sistem belleğinde ham şifreleme anahtarlarına ihtiyaç duyulmamasını önlemenin bir yolu, bunları yalnızca satır içi kripto motorunun anahtar yuvalarında tutmak olacaktır. Ancak bu yaklaşım bazı sorunlarla karşı karşıyadır:
- Şifreleme anahtarlarının sayısı anahtar yuvası sayısını aşabilir.
- Satır içi kripto motorları yalnızca diskteki tüm veri bloklarını şifrelemek/şifresini çözmek için kullanılabilir. Ancak FBE durumunda yazılımın dosya adlarını şifreleme ve anahtar tanımlayıcıları türetme gibi diğer kriptografik işleri yapabilmesi gerekir. Bu diğer işi yapabilmek için yazılımın yine de ham FBE anahtarlarına erişmesi gerekir.
Bu sorunları önlemek için, depolama anahtarları bunun yerine donanımla sarılmış anahtarlara dönüştürülür ve bu anahtarlar yalnızca özel donanım tarafından açılabilir ve kullanılabilir. Bu, sınırsız sayıda anahtarın desteklenmesine olanak tanır. Ek olarak, anahtar hiyerarşisi değiştirildi ve kısmen bu donanıma taşındı; bu, satır içi kripto motorunu kullanamayan görevler için bir alt anahtarın yazılıma döndürülmesine olanak tanıyor.
Anahtar hiyerarşisi
Aşağıdaki şema, donanımla sarılmış anahtarlar kullanılmadığında FBE için tipik bir anahtar hiyerarşisini göstermektedir:
FBE sınıfı anahtarı, belirli bir Android kullanıcısı için kimlik bilgileri ile şifrelenmiş depolama alanı gibi belirli bir şifrelenmiş dizin kümesinin kilidini açmak için Android'in Linux çekirdeğine aktardığı ham şifreleme anahtarıdır. (Çekirdekte bu anahtara fscrypt ana anahtarı denir.) Bu anahtardan çekirdek aşağıdaki alt anahtarları türetir:
- Anahtar tanımlayıcı. Bu, şifreleme için kullanılmaz, daha ziyade belirli bir dosya veya dizinin korunduğu anahtarı tanımlamak için kullanılan bir değerdir.
- Dosya içeriği şifreleme anahtarı
- Dosya adları şifreleme anahtarı
Buna karşılık, aşağıdaki diyagram donanımla sarılmış anahtarlar kullanıldığında FBE için anahtar hiyerarşisini göstermektedir:
Önceki durumla karşılaştırıldığında, anahtar hiyerarşisine ek bir düzey eklendi ve dosya içeriği şifreleme anahtarının yeri değiştirildi. Kök düğüm hala Android'in bir dizi şifrelenmiş dizinin kilidini açmak için Linux'a aktardığı anahtarı temsil ediyor. Ancak artık bu anahtar geçici olarak paketlenmiş durumda ve kullanılabilmesi için özel donanıma aktarılması gerekiyor. Bu donanımın geçici olarak sarılmış bir anahtar alan iki arayüz uygulaması gerekir:
-
inline_encryption_keytüretmek ve onu doğrudan satır içi kripto motorunun anahtar yuvasına programlamak için tek bir arayüz. Bu, yazılımın ham anahtara erişimi olmadan dosya içeriklerinin şifrelenmesine/şifresinin çözülmesine olanak tanır. Android ortak çekirdeklerinde bu arayüz, depolama sürücüsü tarafından uygulanması gereken
blk_crypto_ll_ops::keyslot_programişlemine karşılık gelir.
-
sw_secrettüretmek ve döndürmek için tek bir arayüz ("yazılım sırrı" - bazı yerlerde "ham sır" olarak da adlandırılır), Linux'un dosya içeriği şifrelemesi dışındaki her şey için alt anahtarları türetmek için kullandığı anahtardır. Android ortak çekirdeklerinde bu arayüz, depolama sürücüsü tarafından uygulanması gereken
blk_crypto_ll_ops::derive_sw_secretişlemine karşılık gelir.
Ham depolama anahtarından
inline_encryption_key ve
sw_secret türetmek için donanımın şifreleme açısından güçlü bir KDF kullanması gerekir. Bu KDF, kriptografinin en iyi uygulamalarını takip etmelidir; en az 256 bitlik, yani daha sonra kullanılacak herhangi bir algoritma için yeterli güvenlik gücüne sahip olmalıdır. Ayrıca, elde edilen alt anahtarların kriptografik olarak izole edildiğini, yani bunlardan birinin bilgisinin diğerini açığa çıkarmadığını garanti etmek için her bir alt anahtar türünü türetirken ayrı bir etiket, bağlam ve/veya uygulamaya özel bilgi dizisi kullanması gerekir. Ham depolama anahtarı zaten tekdüze rastgele bir anahtar olduğundan, anahtarın genişletilmesine gerek yoktur.
Teknik olarak güvenlik gereksinimlerini karşılayan herhangi bir KDF kullanılabilir. Ancak test amacıyla aynı KDF'nin test kodunda yeniden uygulanması gerekir. Şu anda bir KDF incelendi ve uygulandı;
vts_kernel_encryption_test kaynak kodunda bulunabilir. Donanımın, PRF olarak AES-256-CMAC ile NIST SP 800-108 "Sayaç Modunda KDF" kullanan bu KDF'yi kullanması önerilir. Uyumlu olabilmesi için, KDF bağlamlarının seçimi ve her alt anahtar için etiketler de dahil olmak üzere algoritmanın tüm parçalarının aynı olması gerektiğini unutmayın.
Anahtar sarma
Donanımla sarılmış anahtarların güvenlik hedeflerini karşılamak için iki tür anahtar sarmalama tanımlanmıştır:
- Geçici sarma : donanım, ham anahtarı, her önyüklemede rastgele oluşturulan ve doğrudan donanımın dışına çıkarılmayan bir anahtar kullanarak şifreler.
- Uzun vadeli sarma : donanım, donanımın dışında doğrudan kullanıma sunulmayan, donanımın içinde yerleşik benzersiz, kalıcı bir anahtar kullanarak ham anahtarı şifreler.
Depolamanın kilidini açmak için Linux çekirdeğine aktarılan tüm anahtarlar geçici olarak paketlenir. Bu, bir saldırganın kullanımdaki bir anahtarı sistem belleğinden çıkarması durumunda, bu anahtarın yalnızca cihaz dışında değil, yeniden başlatmanın ardından cihaz üzerinde de kullanılamaz olmasını sağlar.
Aynı zamanda, Android'in yine de anahtarların şifrelenmiş bir sürümünü diskte saklayabilmesi gerekiyor, böylece ilk etapta kilitlerin açılabilmesi mümkün oluyor. Ham anahtarlar bu amaç için işe yarayacaktır. Bununla birlikte, ham anahtarların hiçbir zaman sistem belleğinde bulunmaması arzu edilir, böylece önyükleme sırasında çıkartılsalar bile cihaz dışında kullanılmak üzere asla çıkartılamazlar. Bu nedenle uzun süreli ambalajlama kavramı tanımlanmıştır.
Anahtarların bu iki farklı yöntemle yönetilmesini desteklemek için donanımın aşağıdaki arayüzleri uygulaması gerekir:
- Depolama anahtarlarını oluşturmak ve içe aktarmak ve bunları uzun vadeli paketlenmiş biçimde döndürmek için arayüzler. Bu arayüzlere KeyMint aracılığıyla dolaylı olarak erişilir ve
TAG_STORAGE_KEYKeyMint etiketine karşılık gelirler. "Oluşturma" yeteneği
voldtarafından Android tarafından kullanılacak yeni depolama anahtarları oluşturmak için kullanılırken, "içe aktarma" yeteneği
vts_kernel_encryption_testtarafından test anahtarlarını içe aktarmak için kullanılır.
- Uzun vadeli sarılmış bir depolama anahtarını geçici olarak sarılmış bir depolama anahtarına dönüştüren bir arayüz. Bu,
convertStorageKeyToEphemeralKeyMint yöntemine karşılık gelir. Bu yöntem, depolamanın kilidini açmak için hem
voldhem de
vts_kernel_encryption_testtarafından kullanılır.
Anahtar sarma algoritması bir uygulama detayıdır ancak rastgele IV'lere sahip AES-256-GCM gibi güçlü bir AEAD kullanmalıdır.
Gerekli yazılım değişiklikleri
AOSP'nin halihazırda donanımla sarılmış anahtarları desteklemek için temel bir çerçevesi vardır. Buna
vold gibi kullanıcı alanı bileşenlerinin yanı sıra blk-crypto , fscrypt ve dm-default-key'deki Linux çekirdek desteği de dahildir.
Ancak uygulamaya özel bazı değişiklikler yapılması gerekmektedir.
KeyMint değişiklikleri
Cihazın KeyMint uygulaması,
TAG_STORAGE_KEY destekleyecek ve
convertStorageKeyToEphemeral yöntemini uygulayacak şekilde değiştirilmelidir.
Keymaster'da,
convertStorageKeyToEphemeral yerine
exportKey kullanıldı.
Linux çekirdeği değişiklikleri
Aygıtın satır içi kripto motorunun Linux çekirdek sürücüsünün, donanımla sarılmış anahtarları destekleyecek şekilde değiştirilmesi gerekir.
android14 ve daha yüksek çekirdekler için
BLK_CRYPTO_KEY_TYPE_HW_WRAPPED
blk_crypto_profile::key_types_supported BLK_CRYPTO_KEY_TYPE_HW_HW_WREPLE SET,
blk_crypto_ll_ops::keyslot_program ve
blk_crypto_ll_ops::keyslot_evict Destek Programlama/EVICING, Blk, Blyging
blk_crypto_ll_ops::derive_sw_secret .
android12 ve
android13 çekirdekleri için,
blk_keyslot_manager::features
BLK_CRYPTO_FEATURE_WRAPPED_KEYS ayarlayın,
blk_ksm_ll_ops::keyslot_program ve
blk_ksm_ll_ops::keyslot_evict donanımla sarılmış anahtarları programlamayı/çıkarmayı desteklemesini sağlayın ve
blk_ksm_ll_ops::derive_raw_secret uygulayın.
android11 çekirdekleri için,
keyslot_manager::features features'da
BLK_CRYPTO_FEATURE_WRAPPED_KEYS ayarlayın,
keyslot_mgmt_ll_ops::keyslot_program vekeyslot_mgmt_ll_ops
keyslot_mgmt_ll_ops::keyslot_evict donanımla sarılmış anahtarları programlamayı/çıkarmayı destekler hale getirin ve
keyslot_mgmt_ll_ops::derive_raw_secret uygulayın.
Test yapmak
Donanımla sarılmış anahtarlarla şifrelemeyi test etmek standart anahtarlarla şifrelemeye göre daha zor olsa da, bir test anahtarını içe aktararak ve donanımın yaptığı anahtar türetmeyi yeniden uygulayarak test etmek yine de mümkündür. Bu,
vts_kernel_encryption_test uygulanır. Bu testi çalıştırmak için şunu çalıştırın:
atest -v vts_kernel_encryption_test
Test günlüğünü okuyun ve donanımla sarılmış anahtar test senaryolarının (örneğin,
FBEPolicyTest.TestAesInlineCryptOptimizedHwWrappedKeyPolicy ve
DmDefaultKeyTest.TestHwWrappedKey ), donanımla sarılmış anahtarlar desteğinin algılanmaması nedeniyle atlanmadığını doğrulayın; çünkü test sonuçları yine de "geçirilir". O vaka.
Etkinleştirme
Cihazın donanımla sarılmış anahtar desteği düzgün bir şekilde çalıştığında, Android'in onu FBE ve meta veri şifrelemesi için kullanmasını sağlamak amacıyla cihazın
fstab dosyasında aşağıdaki değişiklikleri yapabilirsiniz:
- FBE:
wrappedkey_v0bayrağını
fileencryptionparametresine ekleyin. Örneğin,
fileencryption=::inlinecrypt_optimized+wrappedkey_v0kullanın. Daha fazla ayrıntı için FBE belgelerine bakın.
- Meta veri şifreleme:
wrappedkey_v0bayrağını
metadata_encryptionparametresine ekleyin. Örneğin
metadata_encryption=:wrappedkey_v0kullanın. Daha fazla ayrıntı için meta veri şifreleme belgelerine bakın.