Ç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
Anahtarlar, HKDF gibi bir KDF (anahtar türetme işlevi) kullanılarak diğer anahtarlardan türetilebilir ve bu da bir anahtar hiyerarşisine neden olur.
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_key
tü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ı gerekenblk_crypto_ll_ops::keyslot_program
işlemine karşılık gelir. -
sw_secret
tü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ı gerekenblk_crypto_ll_ops::derive_sw_secret
iş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_KEY
KeyMint etiketine karşılık gelirler. "Oluşturma" yeteneğivold
tarafından Android tarafından kullanılacak yeni depolama anahtarları oluşturmak için kullanılırken, "içe aktarma" yeteneğivts_kernel_encryption_test
tarafı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,
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 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_v0
bayrağınıfileencryption
parametresine ekleyin. Örneğin,fileencryption=::inlinecrypt_optimized+wrappedkey_v0
kullanın. Daha fazla ayrıntı için FBE belgelerine bakın. - Meta veri şifreleme:
wrappedkey_v0
bayrağınımetadata_encryption
parametresine ekleyin. Örneğinmetadata_encryption=:wrappedkey_v0
kullanın. Daha fazla ayrıntı için meta veri şifreleme belgelerine bakın.