Ç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ışı bir saldırı sırasında mevcut olmayacaktır. Ancak, soğuk başlatma saldırıları ve bir saldırganın aygıttan tamamen ödün vermeden sistem belleğini sızdırabileceği çevrimiçi saldırılar gibi diğer saldırı türlerine karşı daha fazla koruma sağlama arzusu vardır.
Bu sorunu çözmek için Android 11, donanım desteğinin bulunduğu donanımla sarılmış anahtarlar için destek sağladı. Donanımla sarılmış anahtarlar, yalnızca özel donanıma ham biçimde bilinen depolama anahtarlarıdır; yazılım bu anahtarları yalnızca sarmalanmış (şifreli) biçimde görür ve bunlarla çalışır. Bu donanım, depolama anahtarları oluşturma ve içe aktarma, depolama anahtarlarını geçici ve uzun vadeli biçimlerde sarma, alt anahtarlar türetme, bir alt anahtarı doğrudan bir satır içi şifreleme motoruna programlama ve yazılıma ayrı bir alt anahtar döndürme yeteneğine sahip olmalıdır.
Not : Bir satır içi şifreleme motoru (veya satır içi şifreleme donanımı ), depolama aygıtına giderken/gelirken verileri şifreleyen/şifresini çözen donanımı ifade eder. Genellikle bu, ilgili JEDEC belirtimi tarafından tanımlanan kripto uzantılarını uygulayan bir UFS veya eMMC ana bilgisayar denetleyicisidir.
Tasarım
Bu bölüm, donanımla sarılmış anahtarlar özelliğinin tasarımını, bunun için hangi donanım desteğinin gerekli olduğu da dahil olmak üzere sunar. Bu tartışma, dosya tabanlı şifrelemeye (FBE) odaklanır, ancak çözüm meta veri şifrelemesi için de geçerlidir.
Sistem belleğindeki ham şifreleme anahtarlarına ihtiyaç duymayı önlemenin bir yolu, onları yalnızca bir satır içi şifreleme motorunun anahtar yuvalarında tutmaktır. Ancak bu yaklaşım bazı sorunlarla karşılaşmaktadır:
- Şifreleme anahtarlarının sayısı, anahtar yuvalarının sayısını aşabilir.
- Satır içi şifreleme motorları yalnızca disk üzerindeki tam veri bloklarını şifrelemek/şifresini çözmek için kullanılabilir. Bununla birlikte, 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 yapmak için yazılımın yine de ham FBE anahtarlarına erişmesi gerekir.
Bu sorunlardan kaçınmak için, depolama anahtarları, bunun yerine, yalnızca özel donanım tarafından açılıp kullanılabilen donanımla sarılmış anahtarlara dönüştürülür. Bu, sınırsız sayıda anahtarın desteklenmesine izin verir. Ek olarak, anahtar hiyerarşisi değiştirilir ve kısmen bu donanıma taşınır; bu, bir satır içi kripto motorunu kullanamayan görevler için bir alt anahtarın yazılıma döndürülmesine olanak tanır.
Anahtar hiyerarşi
Anahtarlar, HKDF gibi bir KDF (anahtar türetme işlevi) kullanılarak diğer anahtarlardan türetilebilir, bu da bir anahtar hiyerarşisi ile sonuçlanır.
Aşağıdaki şema, donanımla sarılmış anahtarlar kullanılmadığında FBE için tipik bir anahtar hiyerarşisini gösterir:
FBE sınıf anahtarı, belirli bir Android kullanıcısı için kimlik bilgileriyle şifrelenmiş depolama gibi belirli bir dizi şifreli dizinin kilidini açmak için Android'in Linux çekirdeğine ilettiği 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, bunun yerine 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 şema, donanım sarılı anahtarlar kullanıldığında FBE için anahtar hiyerarşisini gösterir:
Önceki duruma kıyasla, 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 şifreli dizinin kilidini açmak için Linux'a ilettiği anahtarı temsil ediyor. Ancak, artık bu anahtar geçici olarak sarılmış biçimdedir ve kullanılabilmesi için özel donanıma iletilmesi gerekir. Bu donanım, kısa ömürlü bir anahtar alan iki arabirim uygulamalıdır:
-
inline_encryption_key
türetmek ve onu doğrudan satır içi şifreleme motorunun bir anahtar yuvasına programlamak için bir arabirim. Bu, ham anahtara erişimi olan yazılım olmadan dosya içeriğinin şifrelenmesine/şifresinin çözülmesine izin verir. Android ortak çekirdeklerinde bu arabirim, depolama sürücüsü tarafından uygulanması gerekenblk_ksm_ll_ops::keyslot_program
işlemine karşılık gelir. -
sw_secret
türetmek ve döndürmek için bir arabirim ("yazılım sırrı" - bazı yerlerde "ham sır" olarak da adlandırılır), bu, 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 arabirim, depolama sürücüsü tarafından uygulanması gerekenblk_ksm_ll_ops::derive_raw_secret
işlemine karşılık gelir.
Ham depolama anahtarından inline_encryption_key
ve sw_secret
türetmek için donanımın kriptografik olarak güçlü bir KDF kullanması gerekir. Bu KDF, kriptografi en iyi uygulamalarını izlemelidir; en az 256 bitlik bir güvenlik gücüne sahip olmalıdır, yani daha sonra kullanılacak herhangi bir algoritma için yeterli olmalıdır. Ayrıca, ortaya çıkan alt anahtarların kriptografik olarak izole edilmesini garanti etmek için her bir alt anahtar türünü türetirken ayrı bir etiket, bağlam ve/veya uygulamaya özel bilgi dizisi kullanmalıdır, yani bunlardan birinin bilgisi diğerini ortaya çıkarmaz. Ham depolama anahtarı zaten tek tip rastgele bir anahtar olduğundan, anahtar genişletme gerekli değildir.
Teknik olarak, güvenlik gereksinimlerini karşılayan herhangi bir KDF kullanılabilir. Ancak, test amacıyla, aynı KDF'yi test kodunda yeniden uygulamak gerekir. Şu anda bir KDF gözden geçirildi ve uygulandı; vts_kernel_encryption_test
için 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 olması için, her alt anahtar için KDF bağlamları ve etiketleri de dahil olmak üzere, algoritmanın tüm bölümlerinin 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 sarma tanımlanmıştır:
- Geçici sarma : donanım, her önyüklemede rastgele oluşturulan ve donanımın dışında doğrudan gösterilmeyen bir anahtar kullanarak ham anahtarı şifreler.
- Uzun vadeli sarma : donanım, donanımın dışında doğrudan açığa çıkmayan, donanıma yerleşik benzersiz, kalıcı bir anahtar kullanarak ham anahtarı şifreler.
Depolamanın kilidini açmak için Linux çekirdeğine iletilen tüm anahtarlar geçici olarak sarılır. Bu, bir saldırganın kullanımdaki bir anahtarı sistem belleğinden çıkarabilmesi durumunda, bu anahtarın yalnızca cihaz dışında değil, aynı zamanda yeniden başlatmanın ardından cihazda da kullanılamaz hale gelmesini sağlar.
Aynı zamanda, ilk etapta kilitlerinin açılabilmesi için Android'in yine de anahtarların şifreli bir sürümünü diskte saklayabilmesi gerekiyor. Ham anahtarlar bu amaç için çalışır. Bununla birlikte, önyükleme sırasında çıkarılsalar bile, aygıt dışında kullanılmak üzere hiçbir zaman ayıklanamamaları için ham anahtarların sistem belleğinde hiçbir zaman bulunmaması arzu edilir. Bu nedenle uzun süreli sarma kavramı tanımlanmıştır.
Bu iki farklı yolla sarılmış anahtarları yönetmeyi desteklemek için donanımın aşağıdaki arabirimleri uygulaması gerekir:
- Depolama anahtarlarını oluşturmak ve içe aktarmak için arabirimler, bunları uzun vadeli sarmalanmış biçimde döndürür. Bu arayüzlere KeyMint aracılığıyla dolaylı olarak erişilir ve bunlar
TAG_STORAGE_KEY
KeyMint etiketine karşılık gelir. "Oluştur" yeteneği,vold
tarafından Android tarafından kullanılmak üzere yeni depolama anahtarları oluşturmak için kullanılırken, "içe aktar" yeteneği, test anahtarlarını içe aktarmak içinvts_kernel_encryption_test
tarafından kullanılır. - Uzun vadeli sarılmış bir depolama anahtarını geçici olarak sarılmış bir depolama anahtarına dönüştürmek için bir arabirim. Bu,
convertStorageKeyToEphemeral
KeyMint yöntemine karşılık gelir. Bu yöntem, depolamanın kilidini açmak için hemvold
hem devts_kernel_encryption_test
tarafından kullanılır.
Anahtar sarma algoritması bir uygulama ayrıntısıdır, ancak rastgele IV'lerle AES-256-GCM gibi güçlü bir AEAD kullanmalıdır.
Yazılım değişiklikleri gerekli
AOSP, donanımla sarılmış anahtarları desteklemek için zaten temel bir çerçeveye sahiptir. Bu, vold
gibi kullanıcı alanı bileşenlerindeki desteğin yanı sıra blk- crypto, fscrypt ve dm-default- key'deki Linux çekirdek desteğini içerir.
Ancak, uygulamaya özel bazı değişiklikler gereklidir.
KeyMint değişiklikleri
Cihazın KeyMint uygulaması, TAG_STORAGE_KEY
destekleyecek ve convertStorageKeyToEphemeral
yöntemini uygulayacak şekilde değiştirilmelidir.
Keymaster'da convertStorageKeyToEphemeral
exportKey
.
Linux çekirdeği değişiklikleri
Aygıtın satır içi şifreleme motoru için Linux çekirdek sürücüsü, BLK_CRYPTO_FEATURE_WRAPPED_KEYS
ayarlanacak, keyslot_program()
ve keyslot_evict()
işlemlerinin donanımla sarılmış anahtarları programlamayı/çıkarmayı desteklemesini sağlayacak ve derive_raw_secret()
işlemini uygulayacak şekilde değiştirilmelidir.
Test yapmak
Donanımla sarılmış anahtarlarla şifrelemeyi test etmek, standart anahtarlarla şifrelemeyi test etmekten daha zor olsa da, bir test anahtarını içe aktararak ve donanımın yaptığı anahtar türetmesini yeniden uygulayarak test etmek yine de mümkündür. Bu, vts_kernel_encryption_test
içinde 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 için destek algılanmadığından, test sonuçları yine de "geçilmiş" olacağından atlanmadığını doğrulayın. O vaka.
etkinleştirme
Aygıtın donanımla sarılmış anahtar desteği düzgün çalıştığında, Android'in FBE ve meta veri şifreleme için kullanmasını sağlamak için aygıtın fstab
dosyasında aşağıdaki değişiklikleri yapabilirsiniz:
- FBE:
wrappedkey_v0
bayrağınıfileencryption
parametresine ekleyin. Örneğin,fileencryption=::inlinecrypt_optimized+wrappedkey_v0
. Daha fazla ayrıntı için FBE belgelerine bakın. - Meta veri şifreleme:
wrappedkey_v0
bayrağınımetadata_encryption
parametresine ekleyin. Örneğin,metadata_encryption=:wrappedkey_v0
kullanın. Daha fazla ayrıntı için meta veri şifreleme belgelerine bakın.