Enkripsi metadata

Android 7.0 dan yang lebih tinggi mendukung enkripsi berbasis file (FBE). FBE memungkinkan file yang berbeda dienkripsi dengan kunci yang berbeda yang dapat dibuka secara independen. Kunci ini digunakan untuk mengenkripsi konten file dan nama file. Saat FBE digunakan, informasi lain, seperti tata letak direktori, ukuran file, izin, dan waktu pembuatan/modifikasi, tidak dienkripsi. Secara kolektif, informasi lain ini dikenal sebagai metadata sistem file.

Android 9 memperkenalkan dukungan untuk enkripsi metadata. Dengan enkripsi metadata, satu kunci yang ada saat waktu booting mengenkripsi konten apa pun yang tidak dienkripsi oleh FBE. Kunci ini dilindungi oleh KeyMint (sebelumnya Keymaster), yang pada gilirannya dilindungi oleh Booting Terverifikasi.

Enkripsi metadata selalu diaktifkan di penyimpanan yang dapat diadaptasi setiap kali FBE diaktifkan. Enkripsi metadata juga dapat diaktifkan di penyimpanan internal. Perangkat yang diluncurkan dengan Android 11 atau yang lebih tinggi harus mengaktifkan enkripsi metadata di penyimpanan internal.

Implementasi di penyimpanan internal

Anda dapat menyiapkan enkripsi metadata di penyimpanan internal perangkat baru dengan menyiapkan sistem file metadata, mengubah urutan init, dan mengaktifkan enkripsi metadata di file fstab perangkat.

Prasyarat

Enkripsi metadata hanya dapat disiapkan saat partisi data diformat untuk pertama kalinya. Oleh karena itu, fitur ini hanya untuk perangkat baru; hal ini bukan sesuatu yang harus diubah oleh OTA.

Enkripsi metadata mengharuskan modul dm-default-key diaktifkan di kernel Anda. Di Android 11 dan yang lebih tinggi, dm-default-key didukung oleh kernel umum Android, versi 4.14 dan yang lebih tinggi. Versi dm-default-key ini menggunakan framework enkripsi independen hardware dan vendor yang disebut blk-crypto.

Untuk mengaktifkan dm-default-key, gunakan:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_DM_DEFAULT_KEY=y

dm-default-key menggunakan hardware enkripsi inline (hardware yang mengenkripsi/mendekripsi data saat dalam perjalanan ke/dari perangkat penyimpanan) jika tersedia. Jika Anda tidak menggunakan hardware enkripsi inline, Anda juga harus mengaktifkan penggantian ke API kriptografi kernel:

CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

Jika tidak menggunakan hardware enkripsi inline, Anda juga harus mengaktifkan akselerasi berbasis CPU yang tersedia seperti yang direkomendasikan dalam dokumentasi FBE.

Di Android 10 dan yang lebih rendah, dm-default-key tidak didukung oleh kernel umum Android. Oleh karena itu, vendor harus mengimplementasikan dm-default-key.

Menyiapkan sistem file metadata

Karena tidak ada yang dapat dibaca di partisi userdata hingga kunci enkripsi metadata ada, tabel partisi harus menyisihkan partisi terpisah yang disebut partisi metadata untuk menyimpan blob KeyMint yang melindungi kunci ini. Partisi metadata harus berukuran 16 MB.

fstab.hardware harus menyertakan entri untuk sistem file metadata yang ada di partisi tersebut yang dipasang di /metadata, termasuk flag formattable untuk memastikan partisi tersebut diformat saat waktu booting. Sistem file f2fs tidak berfungsi di partisi yang lebih kecil; sebaiknya gunakan ext4. Contoh:

/dev/block/bootdevice/by-name/metadata              /metadata          ext4        noatime,nosuid,nodev,discard                          wait,check,formattable

Untuk memastikan direktori pemasangan /metadata ada, tambahkan baris berikut ke BoardConfig-common.mk:

BOARD_USES_METADATA_PARTITION := true

Perubahan pada urutan init

Saat enkripsi metadata digunakan, vold harus berjalan sebelum /data dipasang. Untuk memastikan enkripsi metadata dimulai cukup awal, tambahkan stanza berikut ke init.hardware.rc:

# We need vold early for metadata encryption
on early-fs
    start vold

KeyMint harus berjalan dan siap sebelum init mencoba memasang /data.

init.hardware.rc harus sudah berisi mount_all petunjuk yang memasang /data itu sendiri di stanza on late-fs. Sebelum baris ini, tambahkan direktif untuk menjalankan layanan wait_for_keymaster:

on late-fs
    
    # Wait for Keymaster
    exec_start wait_for_keymaster

    # Mount RW partitions which need run fsck
    mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

Mengaktifkan enkripsi metadata

Terakhir, tambahkan keydirectory=/metadata/vold/metadata_encryption ke kolom fs_mgr_flags entri fstab untuk userdata. Misalnya, baris fstab lengkap mungkin terlihat seperti ini:

/dev/block/bootdevice/by-name/userdata              /data              f2fs        noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable

Secara default, algoritma enkripsi metadata di penyimpanan internal adalah AES-256-XTS. Algoritma ini dapat diganti dengan menetapkan opsi metadata_encryption, juga di kolom fs_mgr_flags:

  • Di perangkat yang tidak memiliki akselerasi AES, enkripsi Adiantum dapat diaktifkan dengan menetapkan metadata_encryption=adiantum.
  • Di perangkat yang mendukung kunci enkripsi inline yang dienkapsulasi hardware, kunci enkripsi metadata dapat dibuat dienkapsulasi hardware dengan menetapkan metadata_encryption=aes-256-xts:wrappedkey atau metadata_encryption=aes-256-xts:wrappedkey_v0. wrappedkey adalah versi modern; wrappedkey_v0 hanya boleh digunakan di perangkat yang tidak mendukung wrappedkey atau sudah diluncurkan dengan wrappedkey_v0. Untuk mengetahui informasi selengkapnya, lihat Mengaktifkan kunci yang dienkapsulasi.

    Dalam kedua kasus tersebut, aes-256-xts dapat dihilangkan karena merupakan algoritma default. Misalnya, metadata_encryption=:wrappedkey setara dengan metadata_encryption=aes-256-xts:wrappedkey.

Karena antarmuka kernel ke dm-default-key berubah di Android 11, Anda juga harus memastikan bahwa Anda telah menetapkan nilai yang benar untuk PRODUCT_SHIPPING_API_LEVEL di device.mk. Misalnya, jika perangkat Anda diluncurkan dengan Android 11 (level API 30), device.mk harus berisi:

PRODUCT_SHIPPING_API_LEVEL := 30

Anda juga dapat menetapkan properti sistem berikut untuk memaksa penggunaan dm-default-key API baru, terlepas dari API level pengiriman:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.dm_default_key.options_format.version=2

Validasi

Untuk memverifikasi bahwa enkripsi metadata diaktifkan dan berfungsi dengan benar, jalankan pengujian yang dijelaskan di bawah. Perhatikan juga masalah umum yang dijelaskan di bawah.

Pengujian

Mulai dengan menjalankan perintah berikut untuk memverifikasi bahwa enkripsi metadata diaktifkan di penyimpanan internal:

adb root
adb shell dmctl table userdata

Output-nya akan terlihat seperti ini:

Targets in the device-mapper table for userdata:
0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors

Jika Anda mengganti setelan enkripsi default dengan menetapkan opsi metadata_encryption di fstab perangkat, output-nya akan sedikit berbeda dari output di atas. Misalnya, jika Anda mengaktifkan enkripsi Adiantum, kolom ketiga adalah xchacha12,aes-adiantum-plain64 bukan aes-xts-plain64.

Selanjutnya, jalankan vts_kernel_encryption_test untuk memverifikasi kebenaran enkripsi metadata dan FBE:

atest vts_kernel_encryption_test

atau:

vts-tradefed run vts -m vts_kernel_encryption_test

Masalah umum

Selama panggilan ke mount_all, yang memasang partisi /data yang dienkripsi metadata, init menjalankan alat vdc. Alat vdc terhubung ke vold melalui binder untuk menyiapkan perangkat yang dienkripsi metadata dan memasang partisi. Selama panggilan ini, init diblokir, dan upaya untuk membaca atau menetapkan properti init diblokir hingga mount_all selesai. Jika, pada tahap ini, bagian mana pun dari pekerjaan vold diblokir secara langsung atau tidak langsung saat membaca atau menetapkan properti, akan terjadi kebuntuan. Penting untuk memastikan bahwa vold dapat menyelesaikan pekerjaan membaca kunci, berinteraksi dengan KeyMint, dan memasang direktori data tanpa berinteraksi lebih lanjut dengan init.

Jika KeyMint tidak sepenuhnya dimulai saat mount_all berjalan, KeyMint tidak akan merespons vold hingga KeyMint membaca properti tertentu dari init, sehingga menyebabkan kebuntuan yang dijelaskan. Menempatkan exec_start wait_for_keymaster di atas pemanggilan mount_all yang relevan seperti yang ditetapkan akan memastikan KeyMint berjalan sepenuhnya terlebih dahulu dan dengan demikian menghindari kebuntuan ini.

Konfigurasi di penyimpanan yang dapat diadaptasi

Sejak Android 9, bentuk enkripsi metadata selalu diaktifkan di penyimpanan yang dapat digunakan setiap kali FBE diaktifkan, bahkan saat enkripsi metadata tidak diaktifkan di penyimpanan internal.

Di AOSP, ada dua implementasi enkripsi metadata di penyimpanan yang dapat digunakan: yang tidak digunakan lagi berdasarkan dm-crypt, dan yang lebih baru berdasarkan dm-default-key. Untuk memastikan implementasi yang benar dipilih untuk perangkat Anda, pastikan Anda telah menetapkan nilai yang benar untuk PRODUCT_SHIPPING_API_LEVEL di device.mk. Misalnya, jika perangkat Anda diluncurkan dengan Android 11 (level API 30), device.mk harus berisi:

PRODUCT_SHIPPING_API_LEVEL := 30

Anda juga dapat menetapkan properti sistem berikut untuk memaksa penggunaan metode enkripsi metadata volume baru (dan versi kebijakan FBE default baru), terlepas dari API level pengiriman:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.volume.metadata.method=dm-default-key \
    ro.crypto.dm_default_key.options_format.version=2 \
    ro.crypto.volume.options=::v2

Metode saat ini

Di perangkat yang diluncurkan dengan Android 11 atau yang lebih tinggi, enkripsi metadata di penyimpanan yang dapat diadaptasi menggunakan modul kernel dm-default-key, seperti di penyimpanan internal. Lihat prasyarat di atas untuk mengetahui opsi konfigurasi kernel yang akan diaktifkan. Perhatikan bahwa hardware enkripsi inline yang berfungsi di penyimpanan internal perangkat mungkin tidak tersedia di penyimpanan yang dapat diadaptasi, sehingga CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y mungkin diperlukan.

Secara default, metode enkripsi metadata volume dm-default-key menggunakan algoritma enkripsi AES-256-XTS dengan sektor kripto 4096 byte. Algoritma ini dapat diganti dengan menetapkan properti sistem ro.crypto.volume.metadata.encryption. Nilai properti ini memiliki sintaksis yang sama dengan opsi fstab metadata_encryption yang dijelaskan di atas. Misalnya, di perangkat yang tidak memiliki akselerasi AES, enkripsi Adiantum dapat diaktifkan dengan menetapkan ro.crypto.volume.metadata.encryption=adiantum.

Metode lama

Di perangkat yang diluncurkan dengan Android 10 dan yang lebih rendah, enkripsi metadata di penyimpanan yang dapat diadaptasi menggunakan modul kernel dm-crypt, bukan dm-default-key:

CONFIG_DM_CRYPT=y

Tidak seperti metode dm-default-key, metode dm-crypt menyebabkan konten file dienkripsi dua kali: sekali dengan kunci FBE dan sekali dengan kunci enkripsi metadata. Enkripsi ganda ini mengurangi performa dan tidak diperlukan untuk mencapai sasaran keamanan enkripsi metadata, karena Android memastikan bahwa kunci FBE setidaknya sulit dikompromikan seperti kunci enkripsi metadata. Vendor dapat melakukan penyesuaian kernel untuk menghindari enkripsi ganda, khususnya dengan menerapkan opsi allow_encrypt_override yang diteruskan Android ke dm-crypt saat properti sistem ro.crypto.allow_encrypt_override ditetapkan ke true. Penyesuaian ini tidak didukung oleh kernel umum Android.

Secara default, metode enkripsi metadata volume dm-crypt menggunakan algoritma enkripsi AES-128-CBC dengan ESSIV dan sektor kripto 512 byte. Algoritma ini dapat diganti dengan menetapkan properti sistem berikut (yang juga digunakan untuk FDE):

  • ro.crypto.fde_algorithm memilih algoritma enkripsi metadata. Pilihannya adalah aes-128-cbc dan adiantum. Adiantum hanya dapat digunakan jika perangkat tidak memiliki akselerasi AES.
  • ro.crypto.fde_sector_size memilih ukuran sektor kripto. Pilihannya adalah 512, 1024, 2048, dan 4096. Untuk enkripsi Adiantum, gunakan 4096.