رمزگذاری فراداده

اندروید 7.0 و بالاتر از رمزگذاری مبتنی بر فایل (FBE) پشتیبانی می کند. FBE اجازه می دهد تا فایل های مختلف با کلیدهای مختلف رمزگذاری شوند که می توانند به طور مستقل باز شوند. از این کلیدها برای رمزگذاری محتویات و نام فایل ها استفاده می شود. هنگامی که از FBE استفاده می شود، سایر اطلاعات، مانند طرح بندی دایرکتوری، اندازه فایل، مجوزها، و زمان ایجاد/تغییر، رمزگذاری نمی شوند. در مجموع، این اطلاعات دیگر به عنوان فراداده سیستم فایل شناخته می شود.

اندروید 9 پشتیبانی از رمزگذاری ابرداده را معرفی کرد. با رمزگذاری ابرداده، تنها یک کلید موجود در زمان راه‌اندازی، محتوایی را که توسط FBE رمزگذاری نشده است، رمزگذاری می‌کند. این کلید توسط Keymaster محافظت می شود که به نوبه خود توسط بوت تایید شده محافظت می شود.

هر زمان که FBE فعال باشد، رمزگذاری فراداده همیشه در فضای ذخیره سازی قابل قبول فعال است. رمزگذاری متادیتا را می توان در حافظه داخلی نیز فعال کرد. دستگاه‌هایی که با Android 11 یا بالاتر راه‌اندازی می‌شوند باید رمزگذاری ابرداده در حافظه داخلی فعال باشند.

پیاده سازی در حافظه داخلی

می‌توانید با راه‌اندازی سیستم فایل metadata ، تغییر توالی init و فعال کردن رمزگذاری ابرداده در فایل fstab دستگاه، رمزگذاری متادیتا را در حافظه داخلی دستگاه‌های جدید راه‌اندازی کنید.

پیش نیازها

رمزگذاری فراداده تنها زمانی قابل تنظیم است که پارتیشن داده برای اولین بار قالب بندی شود. در نتیجه، این ویژگی فقط برای دستگاه های جدید است. این چیزی نیست که یک OTA باید تغییر دهد.

رمزگذاری متادیتا مستلزم آن است که ماژول dm-default-key در هسته شما فعال باشد. در اندروید 11 و بالاتر، dm-default-key توسط هسته های رایج اندروید، نسخه 4.14 و بالاتر پشتیبانی می شود. این نسخه از dm-default-key از یک چارچوب رمزگذاری مستقل از سخت افزار و فروشنده به نام blk-crypto استفاده می کند.

برای فعال کردن dm-default-key از:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_DM_DEFAULT_KEY=y

dm-default-key از سخت‌افزار رمزگذاری درون خطی (سخت‌افزاری که داده‌ها را هنگامی که در راه است به/از دستگاه ذخیره‌سازی است رمزگذاری/رمزگشایی می‌کند) در صورت وجود استفاده می‌کند. اگر از سخت‌افزار رمزگذاری درون خطی استفاده نمی‌کنید ، لازم است یک بازگشت به API رمزنگاری هسته را نیز فعال کنید:

CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

هنگامی که از سخت افزار رمزگذاری درون خطی استفاده نمی کنید، باید هر گونه شتاب مبتنی بر CPU موجود را همانطور که در اسناد FBE توصیه شده است، فعال کنید.

در اندروید 10 و پایین تر، dm-default-key توسط هسته مشترک اندروید پشتیبانی نمی شد. بنابراین این وظیفه فروشندگان بود که dm-default-key را پیاده سازی کنند.

راه اندازی سیستم فایل فراداده

از آنجایی که تا زمانی که کلید رمزگذاری فراداده وجود نداشته باشد، هیچ چیز در پارتیشن داده‌های کاربر قابل خواندن نیست، جدول پارتیشن باید یک پارتیشن جداگانه به نام "پارتیشن متادیتا" را برای ذخیره کردن حباب‌های keymaster که از این کلید محافظت می‌کنند، کنار بگذارد. پارتیشن متادیتا باید 16 مگابایت باشد.

fstab.hardware باید یک ورودی برای سیستم فایل فراداده که در آن پارتیشن زندگی می کند و آن را در /metadata نصب می کند، شامل پرچم formattable قالب بندی برای اطمینان از فرمت شدن آن در زمان بوت باشد. فایل سیستم f2fs روی پارتیشن های کوچکتر کار نمی کند. توصیه می کنیم به جای آن از ext4 استفاده کنید. مثلا:

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

برای اطمینان از وجود نقطه اتصال /metadata ، خط زیر را به BoardConfig-common.mk اضافه کنید:

BOARD_USES_METADATA_PARTITION := true

تغییرات در توالی init

وقتی از رمزگذاری ابرداده استفاده می‌شود، قبل از نصب /data ، باید vold اجرا شود. برای اطمینان از اینکه به اندازه کافی زود شروع شده است، بیت زیر را به init.hardware.rc اضافه کنید:

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

Keymaster باید در حال اجرا و آماده باشد قبل از اینکه init برای mount /data تلاش کند.

init.hardware.rc از قبل باید حاوی یک دستورالعمل mount_all که خود /data را در مصراع on late-fs mount می کند. قبل از این خط، دستورالعمل را برای اجرای سرویس 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

روشن کردن رمزگذاری ابرداده

در نهایت keydirectory=/metadata/vold/metadata_encryption را به ستون fs_mgr_flags ورودی fstab برای userdata اضافه کنید. به عنوان مثال، یک خط کامل fstab ممکن است به صورت زیر باشد:

/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

به طور پیش فرض، الگوریتم رمزگذاری ابرداده در حافظه داخلی AES-256-XTS است. این را می توان با تنظیم گزینه metadata_encryption ، همچنین در ستون fs_mgr_flags لغو کرد:

  • در دستگاه‌هایی که فاقد شتاب AES هستند، رمزگذاری Adiantum ممکن است با تنظیم metadata_encryption=adiantum فعال شود.
  • در دستگاه‌هایی که از کلیدهای پیچیده‌شده با سخت‌افزار پشتیبانی می‌کنند، کلید رمزگذاری ابرداده را می‌توان با تنظیم metadata_encryption=aes-256-xts:wrappedkey_v0 (یا معادل آن metadata_encryption=:wrappedkey_v0 ، به‌عنوان پیش‌فرض aes-256-xts ) به صورت سخت‌افزاری تبدیل کرد.

از آنجایی که رابط هسته به dm-default-key در Android 11 تغییر کرده است، همچنین باید مطمئن شوید که مقدار صحیح PRODUCT_SHIPPING_API_LEVEL را در device.mk . به عنوان مثال، اگر دستگاه شما با Android 11 (سطح API 30) راه اندازی می شود، device.mk باید شامل موارد زیر باشد:

PRODUCT_SHIPPING_API_LEVEL := 30

همچنین می‌توانید ویژگی سیستم زیر را تنظیم کنید تا بدون در نظر گرفتن سطح API ارسال، از API جدید dm-default-key استفاده شود:

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

اعتبار سنجی

برای تأیید اینکه رمزگذاری ابرداده فعال است و به درستی کار می‌کند، آزمایش‌هایی که در زیر توضیح داده شده است را اجرا کنید. همچنین به مسائل رایجی که در زیر توضیح داده شده است توجه داشته باشید.

تست ها

با اجرای دستور زیر شروع کنید تا تأیید کنید که رمزگذاری ابرداده در حافظه داخلی فعال است:

adb root
adb shell dmctl table userdata

خروجی باید مشابه موارد زیر باشد:

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

اگر با تنظیم گزینه metadata_encryption در fstab دستگاه، تنظیمات رمزگذاری پیش‌فرض را لغو کنید، خروجی کمی با موارد بالا متفاوت خواهد بود. به عنوان مثال، اگر رمزگذاری Adiantum را فعال کرده باشید، قسمت سوم به جای aes-xts-plain64 xchacha12,aes-adiantum-plain64 بود.

سپس، vts_kernel_encryption_test را اجرا کنید تا صحت رمزگذاری ابرداده و FBE را تأیید کنید:

atest vts_kernel_encryption_test

یا:

vts-tradefed run vts -m vts_kernel_encryption_test

مسائل رایج

در طول تماس با mount_all ، که پارتیشن /data رمزگذاری شده با ابرداده را مونتاژ می کند، init ابزار vdc را اجرا می کند. ابزار vold به ولد روی binder متصل می شود تا دستگاه رمزگذاری شده با ابرداده را راه اندازی کرده و پارتیشن را نصب کند. در طول مدت این تماس، init مسدود است، و تلاش برای خواندن یا تنظیم ویژگی‌های init تا زمانی که mount_all تمام شود مسدود می‌شود. اگر در این مرحله، هر بخشی از کار vold به طور مستقیم یا غیرمستقیم در خواندن یا تنظیم یک ویژگی مسدود شود، بن بست ایجاد می شود. مهم است که اطمینان حاصل شود که vold می‌تواند کار خواندن کلیدها، تعامل با Keymaster و نصب فهرست اطلاعات را بدون تعامل بیشتر با init کامل کند.

اگر Keymaster هنگام اجرای mount_all به طور کامل راه‌اندازی نشود vold تا زمانی که ویژگی‌های خاصی را از init نخواند، به ولد پاسخ نمی‌دهد، که دقیقاً منجر به بن‌بست توصیف‌شده می‌شود. قرار دادن exec_start wait_for_keymaster در بالای فراخوان مربوطه mount_all همانطور که مشخص شد، تضمین می‌کند که Keymaster به طور کامل از قبل اجرا می‌شود و بنابراین از این بن‌بست جلوگیری می‌کند.

پیکربندی در ذخیره سازی قابل قبول

از اندروید 9، هر زمان که FBE فعال باشد، نوعی رمزگذاری ابرداده همیشه در فضای ذخیره‌سازی قابل قبول فعال می‌شود، حتی زمانی که رمزگذاری ابرداده در حافظه داخلی فعال نباشد.

در AOSP، دو پیاده‌سازی رمزگذاری ابرداده در فضای ذخیره‌سازی قابل قبول وجود دارد: یکی منسوخ شده بر اساس dm-crypt و دیگری جدیدتر مبتنی بر dm-default-key . برای اطمینان از اینکه پیاده سازی صحیح برای دستگاه شما انتخاب شده است، مطمئن شوید که مقدار صحیح PRODUCT_SHIPPING_API_LEVEL را در device.mk . به عنوان مثال، اگر دستگاه شما با Android 11 (سطح API 30) راه اندازی می شود، device.mk باید شامل موارد زیر باشد:

PRODUCT_SHIPPING_API_LEVEL := 30

همچنین می‌توانید ویژگی‌های سیستم زیر را برای استفاده از روش جدید رمزگذاری فراداده حجم (و نسخه پیش‌فرض جدید خط‌مشی FBE) بدون توجه به سطح API تنظیم کنید:

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

روش فعلی

در دستگاه‌هایی که با Android 11 یا بالاتر راه‌اندازی می‌شوند، رمزگذاری ابرداده در فضای ذخیره‌سازی قابل قبول از ماژول هسته dm-default-key درست مانند حافظه داخلی استفاده می‌کند. پیش نیازهای بالا را ببینید که کدام گزینه های پیکربندی هسته را فعال کنید. توجه داشته باشید که سخت افزار رمزگذاری درون خطی که روی حافظه داخلی دستگاه کار می کند ممکن است در فضای ذخیره سازی قابل قبول در دسترس نباشد، و بنابراین ممکن است CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y مورد نیاز باشد.

به طور پیش فرض، روش رمزگذاری فراداده حجمی dm-default-key از الگوریتم رمزگذاری AES-256-XTS با بخش های کریپتو 4096 بایتی استفاده می کند. الگوریتم را می توان با تنظیم ویژگی ro.crypto.volume.metadata.encryption system لغو کرد. مقدار این ویژگی همان نحوی است که گزینه metadata_encryption fstab که در بالا توضیح داده شد. برای مثال، در دستگاه‌هایی که فاقد شتاب AES هستند، رمزگذاری Adiantum ممکن است با تنظیم ro.crypto.volume.metadata.encryption=adiantum فعال شود.

روش میراثی

در دستگاه‌هایی که با Android 10 یا پایین‌تر راه‌اندازی می‌شوند، رمزگذاری ابرداده در فضای ذخیره‌سازی قابل قبول از ماژول هسته dm-crypt به جای dm-default-key می‌کند:

CONFIG_DM_CRYPT=y

بر خلاف روش dm-default-key ، روش dm-crypt باعث می شود که محتویات فایل دو بار رمزگذاری شوند: یک بار با یک کلید FBE و یک بار با کلید رمزگذاری ابرداده. این رمزگذاری مضاعف عملکرد را کاهش می دهد و برای دستیابی به اهداف امنیتی رمزگذاری ابرداده لازم نیست، زیرا Android تضمین می کند که کلیدهای FBE حداقل به سختی کلید رمزگذاری ابرداده در معرض خطر هستند. فروشندگان می‌توانند سفارشی‌سازی هسته را برای جلوگیری از رمزگذاری مضاعف انجام دهند، به ویژه با اجرای گزینه allow_encrypt_override که وقتی ویژگی سیستم ro.crypto.allow_encrypt_override روی true تنظیم شود، Android به dm-crypt ارسال می‌کند. این سفارشی‌سازی‌ها توسط هسته مشترک اندروید پشتیبانی نمی‌شوند.

به طور پیش فرض، روش رمزگذاری فراداده حجمی dm-crypt از الگوریتم رمزگذاری AES-128-CBC با بخش های رمزنگاری ESSIV و 512 بایتی استفاده می کند. این را می توان با تنظیم ویژگی های سیستم زیر (که برای FDE نیز استفاده می شود) لغو کرد:

  • ro.crypto.fde_algorithm الگوریتم رمزگذاری ابرداده را انتخاب می کند. گزینه‌ها aes-128-cbc و adiantum هستند. Adiantum فقط در صورتی قابل استفاده است که دستگاه فاقد شتاب AES باشد.
  • ro.crypto.fde_sector_size اندازه بخش کریپتو را انتخاب می کند. گزینه ها 512، 1024، 2048 و 4096 هستند. برای رمزگذاری Adiantum، از 4096 استفاده کنید.