رمزگذاری فول دیسک

رمزگذاری کامل دیسک فرآیند رمزگذاری تمام داده‌های کاربر در یک دستگاه اندروید با استفاده از یک کلید رمزگذاری شده است. پس از رمزگذاری یک دستگاه، تمام داده‌های ایجاد شده توسط کاربر قبل از ارسال به دیسک به طور خودکار رمزگذاری می‌شوند و همه داده‌ها قبل از بازگشت به فرآیند فراخوانی، به طور خودکار رمزگشایی می‌شوند.

رمزگذاری کامل دیسک در اندروید ۴.۴ معرفی شد، اما اندروید ۵.۰ این ویژگی‌های جدید را معرفی کرد:

  • رمزگذاری سریعی ایجاد کرد که فقط بلوک‌های استفاده‌شده در پارتیشن داده را رمزگذاری می‌کند تا از زمان طولانی بوت اول جلوگیری شود. در حال حاضر فقط سیستم‌فایل‌های ext4 و f2fs از رمزگذاری سریع پشتیبانی می‌کنند.
  • پرچم forceencrypt fstab برای رمزگذاری در اولین بوت اضافه شد.
  • پشتیبانی از الگوها و رمزگذاری بدون رمز عبور اضافه شد.
  • ذخیره‌سازی سخت‌افزاری کلید رمزگذاری با استفاده از قابلیت امضای Trusted Execution Environment (TEE) (مانند TrustZone) اضافه شد. برای جزئیات بیشتر به ذخیره‌سازی کلید رمزگذاری شده مراجعه کنید.

احتیاط: دستگاه‌هایی که به اندروید ۵.۰ ارتقا یافته و سپس رمزگذاری شده‌اند، می‌توانند با بازنشانی به داده‌های کارخانه به حالت رمزگذاری نشده بازگردند. دستگاه‌های جدید اندروید ۵.۰ که در اولین بوت رمزگذاری شده‌اند، نمی‌توانند به حالت رمزگذاری نشده بازگردند.

نحوه‌ی عملکرد رمزگذاری کامل دیسک اندروید

رمزگذاری کامل دیسک اندروید مبتنی بر dm-crypt است که یک ویژگی هسته است که در لایه دستگاه بلوکی کار می‌کند. به همین دلیل، رمزگذاری با Embedded MultiMediaCard ( eMMC) و دستگاه‌های فلش مشابه که خود را به عنوان دستگاه‌های بلوکی به هسته معرفی می‌کنند، کار می‌کند. رمزگذاری با YAFFS که مستقیماً با یک تراشه فلش NAND خام ارتباط برقرار می‌کند، امکان‌پذیر نیست.

الگوریتم رمزگذاری، استاندارد رمزگذاری پیشرفته ۱۲۸ (AES) با زنجیره بلوکی رمز (CBC) و ESSIV:SHA256 است. کلید اصلی با AES 128 بیتی از طریق فراخوانی کتابخانه OpenSSL رمزگذاری می‌شود. شما باید از ۱۲۸ بیت یا بیشتر برای کلید استفاده کنید (۲۵۶ اختیاری است).

توجه: تولیدکنندگان اصلی تجهیزات (OEM) می‌توانند از رمزگذاری ۱۲۸ بیتی یا بالاتر برای کلید اصلی استفاده کنند.

در نسخه اندروید ۵.۰، چهار نوع حالت رمزگذاری وجود دارد:

  • پیش‌فرض
  • پین
  • رمز عبور
  • الگو

پس از اولین بوت، دستگاه یک کلید اصلی ۱۲۸ بیتی تصادفی ایجاد می‌کند و سپس آن را با یک رمز عبور پیش‌فرض و salt ذخیره شده هش می‌کند. رمز عبور پیش‌فرض "default_password" است. با این حال، هش حاصل نیز از طریق یک TEE (مانند TrustZone) امضا می‌شود که از هش امضا برای رمزگذاری کلید اصلی استفاده می‌کند.

می‌توانید رمز عبور پیش‌فرض تعریف‌شده را در فایل cryptfs.cpp پروژه متن‌باز اندروید پیدا کنید.

وقتی کاربر پین/گذرواژه یا رمز عبور را روی دستگاه تنظیم می‌کند، فقط کلید ۱۲۸ بیتی دوباره رمزگذاری و ذخیره می‌شود. (یعنی تغییرات پین/گذرواژه/الگو کاربر باعث رمزگذاری مجدد داده‌های کاربر نمی‌شود.) توجه داشته باشید که دستگاه مدیریت‌شده ممکن است مشمول محدودیت‌های پین، الگو یا رمز عبور باشد.

رمزگذاری توسط init و vold مدیریت می‌شود. init vold را فراخوانی می‌کند و vold ویژگی‌هایی را برای ایجاد رویدادها در init تنظیم می‌کند. سایر بخش‌های سیستم نیز برای انجام وظایفی مانند گزارش وضعیت، درخواست رمز عبور یا درخواست تنظیم مجدد کارخانه در صورت بروز خطای مهلک، به این ویژگی‌ها نگاه می‌کنند. برای فراخوانی ویژگی‌های رمزگذاری در vold ، سیستم از دستورات cryptfs ابزار خط فرمان vdc استفاده می‌کند: checkpw ، restart ، enablecrypto ، changepw ، cryptocomplete ، verifypw ، setfield ، getfield ، mountdefaultencrypted ، getpwtype ، getpw و clearpw .

برای رمزگذاری، رمزگشایی یا پاک کردن /data ، /data نباید mount شود. با این حال، برای نمایش هرگونه رابط کاربری (UI)، فریم‌ورک باید شروع به کار کند و فریم‌ورک برای اجرا به /data نیاز دارد. برای حل این مشکل، یک سیستم فایل موقت روی /data mount می‌شود. این به اندروید اجازه می‌دهد تا در صورت نیاز رمز عبور درخواست کند، پیشرفت را نشان دهد یا پیشنهاد پاک کردن داده‌ها را بدهد. این محدودیت را اعمال می‌کند که برای تغییر از سیستم فایل موقت به سیستم فایل واقعی /data ، سیستم باید هر فرآیندی را که فایل‌های باز روی سیستم فایل موقت دارد متوقف کند و آن فرآیندها را روی سیستم فایل واقعی /data مجدداً راه‌اندازی کند. برای انجام این کار، همه سرویس‌ها باید در یکی از سه گروه core ، main و late_start باشند.

  • core : هرگز پس از شروع، دستگاه را خاموش نکنید.
  • main : پس از وارد کردن رمز عبور دیسک، سیستم را خاموش و سپس مجدداً راه‌اندازی می‌کند.
  • late_start : تا زمانی که /data رمزگشایی و نصب نشده باشد، شروع به کار نمی‌کند.

برای اجرای این اقدامات، ویژگی vold.decrypt روی رشته‌های مختلف تنظیم می‌شود. برای kill و restart کردن سرویس‌ها، دستورات init عبارتند از:

  • class_reset : یک سرویس را متوقف می‌کند اما اجازه می‌دهد تا با class_start مجدداً راه‌اندازی شود.
  • class_start : یک سرویس را مجدداً راه‌اندازی می‌کند.
  • class_stop : یک سرویس را متوقف می‌کند و یک پرچم SVC_DISABLED اضافه می‌کند. سرویس‌های متوقف شده به class_start پاسخ نمی‌دهند.

جریان‌ها

چهار جریان برای یک دستگاه رمزگذاری شده وجود دارد. یک دستگاه فقط یک بار رمزگذاری می‌شود و سپس یک جریان بوت معمولی را دنبال می‌کند.

  • رمزگذاری دستگاهی که قبلاً رمزگذاری نشده است:
    • رمزگذاری یک دستگاه جدید با forceencrypt : رمزگذاری اجباری در اولین بوت (از اندروید L شروع می‌شود).
    • رمزگذاری یک دستگاه موجود: رمزگذاری آغاز شده توسط کاربر (اندروید K و نسخه‌های قدیمی‌تر).
  • یک دستگاه رمزگذاری شده را بوت کنید:
    • راه‌اندازی یک دستگاه رمزگذاری‌شده بدون رمز عبور: راه‌اندازی یک دستگاه رمزگذاری‌شده که رمز عبور تعیین‌شده‌ای ندارد (مربوط به دستگاه‌هایی که اندروید ۵.۰ و بالاتر دارند).
    • راه‌اندازی یک دستگاه رمزگذاری‌شده با رمز عبور: راه‌اندازی یک دستگاه رمزگذاری‌شده که دارای رمز عبور تنظیم‌شده است.

علاوه بر این جریان‌ها، دستگاه همچنین می‌تواند در رمزگذاری /data ناموفق باشد. هر یک از جریان‌ها در زیر به تفصیل توضیح داده شده‌اند.

رمزگذاری یک دستگاه جدید با forceencrypt

این اولین بوت معمولی برای یک دستگاه اندروید ۵.۰ است.

  1. تشخیص سیستم فایل رمزگذاری نشده با پرچم forceencrypt

    /data رمزگذاری نشده است، اما باید رمزگذاری شود زیرا forceencrypt آن را الزامی می‌کند. /data از حالت mount خارج کنید.

  2. شروع رمزگذاری /data

    vold.decrypt = "trigger_encryption" باعث فعال شدن init.rc می‌شود که باعث می‌شود vold /data را بدون رمز عبور رمزگذاری کند. (هیچ‌کدام تنظیم نشده است زیرا این یک دستگاه جدید است.)

  3. نصب tmpfs

    vold یک فایل tmpfs /data را (با استفاده از گزینه‌های tmpfs از ro.crypto.tmpfs_options ) نصب می‌کند و ویژگی vold.encrypt_progress را روی ۰ تنظیم می‌کند. vold فایل tmpfs /data را برای بوت شدن یک سیستم رمزگذاری شده آماده می‌کند و ویژگی vold.decrypt را روی trigger_restart_min_framework تنظیم می‌کند.

  4. چارچوبی برای نشان دادن پیشرفت ارائه دهید

    از آنجا که دستگاه عملاً هیچ داده‌ای برای رمزگذاری ندارد، نوار پیشرفت اغلب ظاهر نمی‌شود زیرا رمزگذاری خیلی سریع اتفاق می‌افتد. برای جزئیات بیشتر در مورد رابط کاربری پیشرفت، به رمزگذاری یک دستگاه موجود مراجعه کنید.

  5. وقتی /data رمزگذاری شد، فریم‌ورک را از دسترس خارج کن

    vold vold.decrypt به trigger_default_encryption تنظیم می‌کند که سرویس defaultcrypto را شروع می‌کند. (این کار جریان زیر را برای نصب یک userdata رمزگذاری شده پیش‌فرض آغاز می‌کند.) trigger_default_encryption نوع رمزگذاری را بررسی می‌کند تا ببیند آیا /data با رمز عبور رمزگذاری شده است یا بدون آن. از آنجا که دستگاه‌های اندروید ۵.۰ در اولین بوت رمزگذاری می‌شوند، نباید رمز عبوری تنظیم شود. بنابراین ما /data رمزگشایی و نصب می‌کنیم.

  6. نصب /data

    سپس init با استفاده از پارامترهایی که از ro.crypto.tmpfs_options دریافت می‌کند، /data را روی یک RAMDisk از نوع tmpfs سوار می‌کند که در init.rc تنظیم شده است.

  7. چارچوب را شروع کنید

    vold vold.decrypt روی trigger_restart_framework تنظیم می‌کند که فرآیند بوت معمول را ادامه می‌دهد.

رمزگذاری یک دستگاه موجود

این اتفاقی است که هنگام رمزگذاری یک دستگاه اندروید K یا قدیمی‌تر رمزگذاری نشده که به L مهاجرت کرده است، رخ می‌دهد.

این فرآیند توسط کاربر آغاز می‌شود و در کد به آن «رمزگذاری درجا» گفته می‌شود. وقتی کاربر رمزگذاری دستگاه را انتخاب می‌کند، رابط کاربری مطمئن می‌شود که باتری کاملاً شارژ شده و آداپتور برق متناوب به برق وصل است تا برق کافی برای تکمیل فرآیند رمزگذاری وجود داشته باشد.

هشدار: اگر دستگاه قبل از اتمام رمزگذاری خاموش شود و برق آن تمام شود، داده‌های فایل در حالت رمزگذاری جزئی باقی می‌مانند. دستگاه باید به تنظیمات کارخانه بازگردانده شود و تمام داده‌ها از بین می‌روند.

برای فعال کردن رمزگذاری داخلی، vold یک حلقه را برای خواندن هر سکتور از دستگاه بلوک واقعی شروع می‌کند و سپس آن را در دستگاه بلوک رمزنگاری می‌نویسد. vold قبل از خواندن و نوشتن یک سکتور، بررسی می‌کند که آیا در حال استفاده است یا خیر، که این امر رمزگذاری را در دستگاه جدیدی که داده‌های کمی دارد یا اصلاً داده‌ای ندارد، بسیار سریع‌تر می‌کند.

وضعیت دستگاه : ro.crypto.state = "unencrypted" قرار دهید و تریگر init on nonencrypted را برای ادامه بوت اجرا کنید.

  1. رمز عبور را بررسی کنید

    رابط کاربری، vold با دستور cryptfs enablecrypto inplace فراخوانی می‌کند که در آن passwd رمز عبور صفحه قفل کاربر است.

  2. چارچوب را بردارید

    vold خطاها را بررسی می‌کند، اگر نتواند رمزگذاری کند -1 را برمی‌گرداند و دلیل آن را در گزارش چاپ می‌کند. اگر بتواند رمزگذاری کند، ویژگی vold.decrypt را روی trigger_shutdown_framework تنظیم می‌کند. این باعث می‌شود init.rc سرویس‌های موجود در کلاس‌های late_start و main را متوقف کند.

  3. یک پاورقی رمزنگاری ایجاد کنید
  4. یک فایل breadcrumb ایجاد کنید
  5. راه اندازی مجدد
  6. تشخیص فایل breadcrumb
  7. شروع رمزگذاری /data

    سپس vold نگاشت رمزنگاری را تنظیم می‌کند، که یک دستگاه بلوک رمزنگاری مجازی ایجاد می‌کند که بر روی دستگاه بلوک واقعی نگاشت می‌شود اما هر سکتور را هنگام نوشتن رمزگذاری می‌کند و هر سکتور را هنگام خواندن رمزگشایی می‌کند. vold سپس فراداده رمزنگاری را ایجاد و می‌نویسد.

  8. در حین رمزگذاری، tmpfs را mount کنید

    vold یک فایل tmpfs /data را (با استفاده از گزینه‌های tmpfs از ro.crypto.tmpfs_options ) نصب می‌کند و ویژگی vold.encrypt_progress را روی ۰ تنظیم می‌کند. vold فایل tmpfs /data را برای بوت شدن یک سیستم رمزگذاری شده آماده می‌کند و ویژگی vold.decrypt را روی trigger_restart_min_framework تنظیم می‌کند.

  9. چارچوبی برای نشان دادن پیشرفت ارائه دهید

    trigger_restart_min_framework باعث می‌شود init.rc کلاس main سرویس‌ها را آغاز کند. وقتی فریم‌ورک می‌بیند که vold.encrypt_progress روی ۰ تنظیم شده است، رابط کاربری نوار پیشرفت را نمایش می‌دهد که هر پنج ثانیه از آن ویژگی پرس‌وجو می‌کند و نوار پیشرفت را به‌روزرسانی می‌کند. حلقه رمزگذاری هر بار که درصد دیگری از پارتیشن را رمزگذاری می‌کند، vold.encrypt_progress را به‌روزرسانی می‌کند.

  10. وقتی /data رمزگذاری شد، پاورقی crypto را به‌روزرسانی کن

    وقتی /data ‎ با موفقیت رمزگذاری شد، vold پرچم ENCRYPTION_IN_PROGRESS را در فراداده پاک می‌کند.

    وقتی دستگاه با موفقیت قفل‌گشایی شد، از رمز عبور برای رمزگذاری کلید اصلی استفاده می‌شود و پاورقی رمزنگاری به‌روزرسانی می‌شود.

    اگر به هر دلیلی راه‌اندازی مجدد با شکست مواجه شود، vold ویژگی vold.encrypt_progress را روی error_reboot_failed تنظیم می‌کند و رابط کاربری باید پیامی را نمایش دهد که از کاربر می‌خواهد برای راه‌اندازی مجدد، دکمه‌ای را فشار دهد. انتظار نمی‌رود که این اتفاق هرگز رخ دهد.

یک دستگاه رمزگذاری شده را با رمزگذاری پیش‌فرض راه‌اندازی کنید

این اتفاقی است که وقتی یک دستگاه رمزگذاری شده را بدون رمز عبور بوت می‌کنید، می‌افتد. از آنجا که دستگاه‌های اندروید ۵.۰ در اولین بوت رمزگذاری می‌شوند، نباید رمز عبوری تعیین شود و بنابراین این حالت رمزگذاری پیش‌فرض است.

  1. تشخیص /data بدون رمز عبور

    تشخیص دهید که دستگاه اندروید رمزگذاری شده است زیرا /data قابل نصب نیست و یکی از پرچم‌های encryptable یا forceencrypt تنظیم شده است.

    vold vold.decrypt روی trigger_default_encryption تنظیم می‌کند که سرویس defaultcrypto را شروع می‌کند. trigger_default_encryption نوع رمزگذاری را بررسی می‌کند تا ببیند آیا /data با رمز عبور رمزگذاری شده است یا بدون آن.

  2. رمزگشایی /داده‌ها

    دستگاه dm-crypt را روی دستگاه بلوکی ایجاد می‌کند تا دستگاه آماده استفاده شود.

  3. نصب /داده

    سپس vold پارتیشن رمزگشایی شده‌ی real /data را mount کرده و پارتیشن جدید را آماده می‌کند. این دستور، ویژگی vold.post_fs_data_done را روی ۰ تنظیم می‌کند و سپس vold.decrypt را روی trigger_post_fs_data تنظیم می‌کند. این باعث می‌شود init.rc دستورات post-fs-data خود را اجرا کند. آن‌ها دایرکتوری‌ها یا لینک‌های لازم را ایجاد کرده و سپس vold.post_fs_data_done را روی ۱ تنظیم می‌کنند.

    به محض اینکه vold عدد ۱ را در آن ویژگی ببیند، ویژگی vold.decrypt را به trigger_restart_framework. این باعث می‌شود که init.rc دوباره سرویس‌های کلاس main را شروع کند و همچنین برای اولین بار از زمان بوت، سرویس‌های کلاس late_start را نیز شروع کند.

  4. چارچوب را شروع کنید

    اکنون این چارچوب تمام سرویس‌های خود را با استفاده از /data رمزگشایی شده بوت می‌کند و سیستم آماده استفاده است.

راه‌اندازی یک دستگاه رمزگذاری‌شده بدون رمزگذاری پیش‌فرض

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

  1. تشخیص دستگاه رمزگذاری شده با رمز عبور

    تشخیص می‌دهد که دستگاه اندروید رمزگذاری شده است زیرا پرچم ro.crypto.state = "encrypted"

    vold vold.decrypt به trigger_restart_min_framework تنظیم می‌کند زیرا /data با یک رمز عبور رمزگذاری شده است.

  2. نصب tmpfs

    init پنج ویژگی برای ذخیره گزینه‌های اولیه mount که برای /data با پارامترهای ارسالی از init.rc داده شده است، تنظیم می‌کند. vold از این ویژگی‌ها برای تنظیم نگاشت رمزنگاری استفاده می‌کند:

    1. ro.crypto.fs_type
    2. ro.crypto.fs_real_blkdev
    3. ro.crypto.fs_mnt_point
    4. ro.crypto.fs_options
    5. ro.crypto.fs_flags (عدد هگز هشت رقمی ASCII که قبل از آن 0x قرار دارد)
  3. شروع فریم‌ورک برای درخواست رمز عبور

    فریم‌ورک شروع به کار می‌کند و می‌بیند که vold.decrypt روی trigger_restart_min_framework تنظیم شده است. این به فریم‌ورک می‌گوید که روی دیسک tmpfs /data بوت می‌شود و باید رمز عبور کاربر را دریافت کند.

    با این حال، ابتدا باید مطمئن شود که دیسک به درستی رمزگذاری شده است. دستور cryptfs cryptocomplete به vold ارسال می‌کند. vold در صورت موفقیت‌آمیز بودن رمزگذاری، مقدار ۰، در صورت خطای داخلی مقدار -۱ و در صورت عدم موفقیت رمزگذاری، مقدار -۲ را برمی‌گرداند. vold این موضوع را با جستجوی فراداده رمزنگاری برای پرچم CRYPTO_ENCRYPTION_IN_PROGRESS تعیین می‌کند. اگر این پرچم تنظیم شده باشد، فرآیند رمزگذاری قطع شده و هیچ داده قابل استفاده‌ای روی دستگاه وجود ندارد. اگر vold خطایی را برگرداند، رابط کاربری باید پیامی را برای راه‌اندازی مجدد و تنظیم مجدد کارخانه دستگاه به کاربر نمایش دهد و دکمه‌ای را برای انجام این کار در اختیار کاربر قرار دهد.

  4. رمزگشایی داده‌ها با رمز عبور

    پس از موفقیت‌آمیز بودن cryptfs cryptocomplete ، چارچوب یک رابط کاربری (UI) نمایش می‌دهد که رمز عبور دیسک را درخواست می‌کند. رابط کاربری با ارسال دستور cryptfs checkpw به vold ، رمز عبور را بررسی می‌کند. اگر رمز عبور صحیح باشد (که با نصب موفقیت‌آمیز فایل رمزگشایی شده /data در یک مکان موقت و سپس لغو نصب آن مشخص می‌شود)، vold نام دستگاه بلوک رمزگشایی شده را در ویژگی ro.crypto.fs_crypto_blkdev ذخیره می‌کند و وضعیت 0 را به رابط کاربری برمی‌گرداند. اگر رمز عبور نادرست باشد، -1 را به رابط کاربری برمی‌گرداند.

  5. چارچوب را متوقف کنید

    رابط کاربری یک تصویر بوت رمزنگاری را نمایش می‌دهد و سپس vold با دستور cryptfs restart فراخوانی می‌کند. vold ویژگی vold.decrypt را روی trigger_reset_main تنظیم می‌کند که باعث می‌شود init.rc تابع class_reset main را اجرا کند. این کار تمام سرویس‌های کلاس main را متوقف می‌کند و به tmpfs /data اجازه می‌دهد تا unmount شوند.

  6. نصب /data

    سپس vold پارتیشن رمزگشایی‌شده‌ی real /data را mount می‌کند و پارتیشن جدید را آماده می‌کند (که اگر با گزینه‌ی wipe رمزگذاری می‌شد، ممکن بود هرگز آماده نشود، که در نسخه‌ی اول پشتیبانی نمی‌شود). این دستور، ویژگی vold.post_fs_data_done را روی ۰ تنظیم می‌کند و سپس vold.decrypt را روی trigger_post_fs_data تنظیم می‌کند. این باعث می‌شود init.rc دستورات post-fs-data خود را اجرا کند. آن‌ها دایرکتوری‌ها یا لینک‌های لازم را ایجاد می‌کنند و سپس vold.post_fs_data_done را روی ۱ تنظیم می‌کنند. وقتی vold عدد ۱ را در آن ویژگی می‌بیند، ویژگی vold.decrypt را روی trigger_restart_framework تنظیم می‌کند. این باعث می‌شود init.rc دوباره سرویس‌های کلاس main را شروع کند و همچنین برای اولین بار از زمان بوت، سرویس‌های کلاس late_start را شروع کند.

  7. شروع فریم‌ورک کامل

    اکنون این چارچوب تمام سرویس‌های خود را با استفاده از سیستم فایل رمزگشایی‌شده‌ی /data بوت می‌کند و سیستم آماده‌ی استفاده است.

شکست

دستگاهی که رمزگشایی نمی‌شود، ممکن است به چند دلیل مشکل داشته باشد. دستگاه با یک سری مراحل معمول برای بوت شدن شروع می‌شود:

  1. تشخیص دستگاه رمزگذاری شده با رمز عبور
  2. نصب tmpfs
  3. شروع فریم‌ورک برای درخواست رمز عبور

اما پس از باز شدن چارچوب، دستگاه ممکن است با برخی خطاها مواجه شود:

  • رمز عبور مطابقت دارد اما نمی‌تواند داده‌ها را رمزگشایی کند
  • کاربر 30 بار رمز عبور را اشتباه وارد می‌کند

اگر این خطاها برطرف نشدند، از کاربر بخواهید که تنظیمات کارخانه را پاک کند :

اگر vold در طول فرآیند رمزگذاری خطایی را تشخیص دهد، و اگر هنوز هیچ داده‌ای از بین نرفته باشد و چارچوب فعال باشد، vold ویژگی vold.encrypt_progress را روی error_not_encrypted تنظیم می‌کند. رابط کاربری از کاربر می‌خواهد که سیستم را مجدداً راه‌اندازی کند و به او هشدار می‌دهد که فرآیند رمزگذاری هرگز شروع نشده است. اگر خطا پس از حذف چارچوب رخ دهد، اما قبل از اینکه رابط کاربری نوار پیشرفت فعال شود، vold سیستم را مجدداً راه‌اندازی می‌کند. اگر راه‌اندازی مجدد ناموفق باشد، vold.encrypt_progress روی error_shutting_down تنظیم می‌کند و -1 را برمی‌گرداند؛ اما چیزی برای گرفتن خطا وجود نخواهد داشت. انتظار نمی‌رود که این اتفاق بیفتد.

اگر vold در طول فرآیند رمزگذاری خطایی را تشخیص دهد، vold.encrypt_progress را روی error_partially_encrypted تنظیم می‌کند و -1 را برمی‌گرداند. سپس رابط کاربری باید پیامی مبنی بر عدم موفقیت رمزگذاری نمایش دهد و دکمه‌ای برای کاربر فراهم کند تا دستگاه را به تنظیمات کارخانه برگرداند.

کلید رمزگذاری شده را ذخیره کنید

کلید رمزگذاری شده در فراداده رمزنگاری ذخیره می‌شود. پشتیبانی سخت‌افزاری با استفاده از قابلیت امضای محیط اجرای مطمئن (TEE) پیاده‌سازی می‌شود. پیش از این، ما کلید اصلی را با کلیدی که با اعمال scrypt به رمز عبور کاربر و salt ذخیره شده تولید می‌شد، رمزگذاری می‌کردیم. برای اینکه کلید در برابر حملات خارج از جعبه مقاوم شود، این الگوریتم را با امضای کلید حاصل با یک کلید TEE ذخیره شده گسترش می‌دهیم. امضای حاصل سپس با یک بار دیگر اعمال scrypt به یک کلید با طول مناسب تبدیل می‌شود. سپس از این کلید برای رمزگذاری و رمزگشایی کلید اصلی استفاده می‌شود. برای ذخیره این کلید:

  1. کلید رمزگذاری دیسک تصادفی ۱۶ بایتی (DEK) و سالت ۱۶ بایتی تولید کنید.
  2. برای تولید کلید میانی ۳۲ بایتی ۱ (IK1)، scrypt را روی رمز عبور کاربر و salt اعمال کنید.
  3. IK1 را با صفر بایت به اندازه کلید خصوصی سخت‌افزاری (HBK) پدگذاری می‌کنیم. به طور خاص، ما به صورت زیر پدگذاری می‌کنیم: ۰۰ || IK1 || ۰۰..۰۰؛ یک صفر بایت، ۳۲ بایت IK1، ۲۲۳ صفر بایت.
  4. علامت IK1 با HBK پر شده تا IK2 256 بایتی تولید کند.
  5. برای تولید IK3 با حجم ۳۲ بایت، اسکریپت (scrypt) و نمک (salt) (همان نمک مرحله ۲) را روی IK2 اعمال کنید.
  6. از ۱۶ بایت اول IK3 به عنوان KEK و ۱۶ بایت آخر به عنوان IV استفاده کنید.
  7. DEK را با AES_CBC، با کلید KEK و بردار مقداردهی اولیه IV رمزگذاری کنید.

رمز عبور را تغییر دهید

وقتی کاربری تصمیم می‌گیرد رمز عبور خود را در تنظیمات تغییر دهد یا حذف کند، رابط کاربری دستور cryptfs changepw به vold ارسال می‌کند و vold کلید اصلی دیسک را با رمز عبور جدید دوباره رمزگذاری می‌کند.

ویژگی‌های رمزگذاری

vold و init با تنظیم ویژگی‌ها با یکدیگر ارتباط برقرار می‌کنند. در اینجا لیستی از ویژگی‌های موجود برای رمزگذاری آمده است.

خواص ولت

ملک توضیحات
vold.decrypt trigger_encryption درایو را بدون رمز عبور رمزگذاری کنید.
vold.decrypt trigger_default_encryption درایو را بررسی کنید تا ببینید آیا بدون رمز عبور رمزگذاری شده است یا خیر. اگر چنین است، آن را رمزگشایی و نصب کنید، در غیر این صورت vold.decrypt را روی trigger_restart_min_framework تنظیم کنید.
vold.decrypt trigger_reset_main توسط vold تنظیم شده است تا رابط کاربری را با درخواست رمز عبور دیسک خاموش کند.
vold.decrypt trigger_post_fs_data توسط vold تنظیم می‌شود تا /data با دایرکتوری‌های لازم آماده کند و غیره.
vold.decrypt trigger_restart_framework توسط vold تنظیم شده تا فریم‌ورک واقعی و تمام سرویس‌ها شروع به کار کنند.
vold.decrypt trigger_shutdown_framework توسط vold تنظیم شده است تا کل فریم‌ورک را برای شروع رمزگذاری خاموش کند.
vold.decrypt trigger_restart_min_framework توسط vold تنظیم می‌شود تا رابط کاربری نوار پیشرفت برای رمزگذاری شروع شود یا بسته به مقدار ro.crypto.state درخواست رمز عبور کند.
vold.encrypt_progress وقتی فریم‌ورک شروع به کار می‌کند، اگر این ویژگی تنظیم شده باشد، وارد حالت رابط کاربری نوار پیشرفت می‌شود.
vold.encrypt_progress 0 to 100 رابط کاربری نوار پیشرفت باید درصد مقدار تعیین شده را نمایش دهد.
vold.encrypt_progress error_partially_encrypted رابط کاربری نوار پیشرفت باید پیامی مبنی بر عدم موفقیت رمزگذاری نمایش دهد و به کاربر گزینه‌ای برای تنظیم مجدد کارخانه دستگاه بدهد.
vold.encrypt_progress error_reboot_failed رابط کاربری نوار پیشرفت باید پیامی مبنی بر تکمیل رمزگذاری نمایش دهد و به کاربر دکمه‌ای برای راه‌اندازی مجدد دستگاه بدهد. انتظار نمی‌رود این خطا رخ دهد.
vold.encrypt_progress error_not_encrypted رابط کاربری نوار پیشرفت باید پیامی مبنی بر وقوع خطا، عدم رمزگذاری یا از دست رفتن هیچ داده‌ای را نمایش دهد و به کاربر دکمه‌ای برای راه‌اندازی مجدد سیستم بدهد.
vold.encrypt_progress error_shutting_down رابط کاربری نوار پیشرفت اجرا نمی‌شود، بنابراین مشخص نیست چه کسی به این خطا پاسخ می‌دهد. و در هر صورت هرگز نباید این اتفاق بیفتد.
vold.post_fs_data_done 0 درست قبل از تنظیم vold.decrypt روی trigger_post_fs_data توسط vold تنظیم شده است.
vold.post_fs_data_done 1 توسط init.rc یا init.rc درست پس از اتمام وظیفه post-fs-data تنظیم می‌شود.

ویژگی‌های اولیه

ملک توضیحات
ro.crypto.fs_crypto_blkdev با دستور vold checkpw برای استفاده‌های بعدی با دستور vold restart تنظیم می‌شود.
ro.crypto.state unencrypted با init تنظیم می‌شود تا بگوید این سیستم با یک /data ro.crypto.state encrypted در حال اجرا است. با init تنظیم می‌شود تا بگوید این سیستم با یک /data رمزگذاری شده در حال اجرا است.

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags

این پنج ویژگی توسط init تنظیم می‌شوند، زمانی که سعی می‌کند /data با پارامترهای ارسالی از init.rc سوار کند. vold از این موارد برای تنظیم نگاشت رمزنگاری استفاده می‌کند.
ro.crypto.tmpfs_options توسط init.rc و با گزینه‌هایی که init باید هنگام mount کردن فایل سیستم tmpfs /data استفاده کند، تنظیم شده است.

اقدامات اولیه

on post-fs-data
on nonencrypted
on property:vold.decrypt=trigger_reset_main
on property:vold.decrypt=trigger_post_fs_data
on property:vold.decrypt=trigger_restart_min_framework
on property:vold.decrypt=trigger_restart_framework
on property:vold.decrypt=trigger_shutdown_framework
on property:vold.decrypt=trigger_encryption
on property:vold.decrypt=trigger_default_encryption