ফুল-ডিস্ক এনক্রিপশন

ফুল-ডিস্ক এনক্রিপশন হলো একটি এনক্রিপ্টেড কী ব্যবহার করে অ্যান্ড্রয়েড ডিভাইসের সমস্ত ব্যবহারকারীর ডেটা এনকোড করার প্রক্রিয়া। একবার কোনো ডিভাইস এনক্রিপ্ট করা হলে, ব্যবহারকারীর তৈরি করা সমস্ত ডেটা ডিস্কে সংরক্ষণের আগে স্বয়ংক্রিয়ভাবে এনক্রিপ্ট হয়ে যায় এবং সমস্ত রিড অপারেশন কলিং প্রসেসে ডেটা ফেরত পাঠানোর আগে স্বয়ংক্রিয়ভাবে ডিক্রিপ্ট করে নেয়।

অ্যান্ড্রয়েড ৪.৪ সংস্করণে সম্পূর্ণ-ডিস্ক এনক্রিপশন চালু করা হয়েছিল, কিন্তু অ্যান্ড্রয়েড ৫.০-তে এই নতুন বৈশিষ্ট্যগুলো আনা হয়েছে:

  • দ্রুত এনক্রিপশন তৈরি করা হয়েছে, যা শুধুমাত্র ডেটা পার্টিশনের ব্যবহৃত ব্লকগুলোকে এনক্রিপ্ট করে, ফলে প্রথম বুট হতে বেশি সময় লাগে না। বর্তমানে শুধু ext4 এবং f2fs ফাইলসিস্টেমগুলো দ্রুত এনক্রিপশন সমর্থন করে।
  • প্রথম বুটে এনক্রিপ্ট করার জন্য forceencrypt fstab ফ্ল্যাগটি যোগ করা হয়েছে।
  • পাসওয়ার্ড ছাড়াই প্যাটার্ন ও এনক্রিপশনের সুবিধা যোগ করা হয়েছে।
  • ট্রাস্টেড এক্সিকিউশন এনভায়রনমেন্টের (TEE) সাইনিং ক্ষমতা ব্যবহার করে এনক্রিপশন কী-এর হার্ডওয়্যার-সমর্থিত স্টোরেজ যুক্ত করা হয়েছে (যেমন একটি ট্রাস্টজোনে)। আরও বিস্তারিত জানতে ‘এনক্রিপ্ট করা কী সংরক্ষণ’ দেখুন।

সতর্কতা: যে ডিভাইসগুলো অ্যান্ড্রয়েড ৫.০-তে আপগ্রেড করার পর এনক্রিপ্ট করা হয়েছে, সেগুলোকে ফ্যাক্টরি ডেটা রিসেটের মাধ্যমে আনএনক্রিপ্টেড অবস্থায় ফিরিয়ে আনা যেতে পারে। প্রথম বুটে এনক্রিপ্ট করা নতুন অ্যান্ড্রয়েড ৫.০ ডিভাইসগুলোকে আনএনক্রিপ্টেড অবস্থায় ফিরিয়ে আনা যায় না।

অ্যান্ড্রয়েড ফুল-ডিস্ক এনক্রিপশন কীভাবে কাজ করে

অ্যান্ড্রয়েড ফুল-ডিস্ক এনক্রিপশন dm-crypt উপর ভিত্তি করে তৈরি, যা একটি কার্নেল ফিচার এবং ব্লক ডিভাইস লেয়ারে কাজ করে। এই কারণে, এমবেডেড মাল্টিমিডিয়া কার্ড ( eMMC) এবং একই ধরনের ফ্ল্যাশ ডিভাইস, যেগুলো কার্নেলের কাছে নিজেদেরকে ব্লক ডিভাইস হিসেবে উপস্থাপন করে, সেগুলোর সাথে এনক্রিপশন কাজ করে। YAFFS-এর সাথে এনক্রিপশন সম্ভব নয়, কারণ এটি সরাসরি একটি র ন্যান্ড ফ্ল্যাশ চিপের সাথে যোগাযোগ করে।

এনক্রিপশন অ্যালগরিদমটি হলো সাইফার-ব্লক চেইনিং (CBC) সহ ১২৮-বিট অ্যাডভান্সড এনক্রিপশন স্ট্যান্ডার্ড (AES) এবং ESSIV:SHA256। মাস্টার কী-টি OpenSSL লাইব্রেরিকে কল করার মাধ্যমে ১২৮-বিট AES দিয়ে এনক্রিপ্ট করা হয়। কী-টির জন্য আপনাকে অবশ্যই ১২৮ বিট বা তার বেশি ব্যবহার করতে হবে (২৫৬ বিট ঐচ্ছিক)।

দ্রষ্টব্য: OEM-রা মাস্টার কী এনক্রিপ্ট করার জন্য ১২৮-বিট বা তার বেশি ব্যবহার করতে পারে।

অ্যান্ড্রয়েড ৫.০ সংস্করণে চার ধরনের এনক্রিপশন অবস্থা রয়েছে:

  • ডিফল্ট
  • পিন
  • পাসওয়ার্ড
  • প্যাটার্ন

প্রথমবার চালু হওয়ার সময়, ডিভাইসটি এলোমেলোভাবে একটি ১২৮-বিটের মাস্টার কী তৈরি করে এবং তারপর সেটিকে একটি ডিফল্ট পাসওয়ার্ড ও সংরক্ষিত সল্ট দিয়ে হ্যাশ করে। ডিফল্ট পাসওয়ার্ডটি হলো: "default_password"। তবে, প্রাপ্ত হ্যাশটি একটি TEE (যেমন TrustZone)-এর মাধ্যমে স্বাক্ষরিতও হয়, যা মাস্টার কী এনক্রিপ্ট করার জন্য স্বাক্ষরের হ্যাশটি ব্যবহার করে।

আপনি অ্যান্ড্রয়েড ওপেন সোর্স প্রজেক্টের cryptfs.cpp ফাইলে ডিফল্ট পাসওয়ার্ডটি খুঁজে পাবেন।

যখন ব্যবহারকারী ডিভাইসে পিন/পাস বা পাসওয়ার্ড সেট করেন, তখন শুধুমাত্র ১২৮-বিটের কী-টি পুনরায় এনক্রিপ্ট করে সংরক্ষণ করা হয়। (অর্থাৎ, ব্যবহারকারীর পিন/পাস/প্যাটার্ন পরিবর্তনের কারণে ইউজারডেটা পুনরায় এনক্রিপ্ট হয় না।) উল্লেখ্য যে, পরিচালিত ডিভাইসটি পিন, প্যাটার্ন বা পাসওয়ার্ড সংক্রান্ত বিধিনিষেধের অধীন হতে পারে।

এনক্রিপশন init এবং vold দ্বারা পরিচালিত হয়। init , vold কে কল করে এবং vold, init-এর ইভেন্টগুলো ট্রিগার করার জন্য প্রোপার্টি সেট করে। সিস্টেমের অন্যান্য অংশও স্ট্যাটাস রিপোর্ট করা, পাসওয়ার্ড চাওয়া, বা কোনো মারাত্মক ত্রুটির ক্ষেত্রে ফ্যাক্টরি রিসেট করার জন্য প্রম্পট করার মতো কাজগুলো সম্পাদন করতে এই প্রোপার্টিগুলো দেখে। vold এ এনক্রিপশন ফিচারগুলো চালু করার জন্য, সিস্টেমটি কমান্ড লাইন টুল vdc এর cryptfs কমান্ডগুলো ব্যবহার করে: checkpw , restart , enablecrypto , changepw , cryptocomplete , verifypw , setfield , getfield , mountdefaultencrypted , getpwtype , getpw , এবং clearpw

/data এনক্রিপ্ট, ডিক্রিপ্ট বা ওয়াইপ করার জন্য, /data মাউন্ট করা থাকা যাবে না। তবে, যেকোনো ইউজার ইন্টারফেস (UI) দেখানোর জন্য ফ্রেমওয়ার্কটি চালু হতে হয় এবং ফ্রেমওয়ার্কটি চলার জন্য /data প্রয়োজন। এই সমস্যার সমাধান করতে, /data তে একটি অস্থায়ী ফাইলসিস্টেম মাউন্ট করা হয়। এর ফলে অ্যান্ড্রয়েড প্রয়োজন অনুযায়ী পাসওয়ার্ড চাইতে, কাজের অগ্রগতি দেখাতে বা ডেটা ওয়াইপ করার পরামর্শ দিতে পারে। তবে এর একটি সীমাবদ্ধতা হলো, অস্থায়ী ফাইলসিস্টেম থেকে আসল /data ফাইলসিস্টেমে ফিরে যেতে হলে, সিস্টেমকে অবশ্যই অস্থায়ী ফাইলসিস্টেমে ফাইল খোলা থাকা প্রতিটি প্রসেস বন্ধ করতে হবে এবং আসল /data ফাইলসিস্টেমে সেই প্রসেসগুলো পুনরায় চালু করতে হবে। এটি করার জন্য, সমস্ত সার্ভিসকে অবশ্যই core , main এবং late_start এই তিনটি গ্রুপের যেকোনো একটিতে থাকতে হবে।

  • core : একবার চালু হলে আর বন্ধ হয় না।
  • main : ডিস্ক পাসওয়ার্ড প্রবেশ করানোর পর শাট ডাউন করে পুনরায় চালু করুন।
  • late_start : /data ডিক্রিপ্ট এবং মাউন্ট না হওয়া পর্যন্ত এটি চালু হয় না।

এই ক্রিয়াগুলি শুরু করতে, vold.decrypt প্রপার্টিটি বিভিন্ন স্ট্রিং -এ সেট করা হয়। সার্ভিস বন্ধ ও পুনরায় চালু করার জন্য init কমান্ডগুলি হলো:

  • class_reset : একটি সার্ভিস বন্ধ করে দেয়, কিন্তু class_start ব্যবহার করে এটিকে পুনরায় চালু করার সুযোগ দেয়।
  • class_start : একটি সার্ভিস পুনরায় চালু করে।
  • class_stop : একটি সার্ভিস বন্ধ করে এবং একটি SVC_DISABLED ফ্ল্যাগ যোগ করে। বন্ধ থাকা সার্ভিসগুলো class_start এ সাড়া দেয় না।

প্রবাহ

একটি এনক্রিপ্টেড ডিভাইসের জন্য চারটি প্রবাহ রয়েছে। একটি ডিভাইস কেবল একবার এনক্রিপ্ট করা হয় এবং তারপর একটি স্বাভাবিক বুট প্রবাহ অনুসরণ করে।

  • পূর্বে এনক্রিপ্ট করা হয়নি এমন একটি ডিভাইস এনক্রিপ্ট করুন:
    • forceencrypt দিয়ে একটি নতুন ডিভাইস এনক্রিপ্ট করুন: প্রথম বুটে বাধ্যতামূলক এনক্রিপশন (Android L থেকে শুরু)।
    • বিদ্যমান ডিভাইস এনক্রিপ্ট করুন: ব্যবহারকারী-প্রবর্তিত এনক্রিপশন (অ্যান্ড্রয়েড কে এবং পূর্ববর্তী সংস্করণ)।
  • একটি এনক্রিপ্টেড ডিভাইস বুট করুন:
    • পাসওয়ার্ড ছাড়া এনক্রিপ্টেড ডিভাইস চালু করা: এমন একটি এনক্রিপ্টেড ডিভাইস বুট করা যাতে কোনো পাসওয়ার্ড সেট করা নেই (অ্যান্ড্রয়েড ৫.০ এবং তার পরবর্তী সংস্করণে চালিত ডিভাইসগুলোর জন্য প্রযোজ্য)।
    • পাসওয়ার্ড দিয়ে এনক্রিপ্টেড ডিভাইস চালু করা: একটি এনক্রিপ্টেড ডিভাইস বুট করা, যেটিতে একটি পাসওয়ার্ড সেট করা আছে।

এই ত্রুটিগুলো ছাড়াও, ডিভাইসটি /data এনক্রিপ্ট করতে ব্যর্থ হতে পারে। প্রতিটি ত্রুটি নিচে বিস্তারিতভাবে ব্যাখ্যা করা হলো।

ফোর্সএনক্রিপ্ট দিয়ে একটি নতুন ডিভাইস এনক্রিপ্ট করুন

এটি একটি অ্যান্ড্রয়েড ৫.০ ডিভাইসের স্বাভাবিক প্রথম বুট।

  1. forceencrypt ফ্ল্যাগ ব্যবহার করে এনক্রিপ্ট করা হয়নি এমন ফাইলসিস্টেম সনাক্ত করুন

    /data এনক্রিপ্ট করা নেই, কিন্তু forceencrypt নির্দেশ অনুযায়ী এটি এনক্রিপ্ট করা প্রয়োজন। /data আনমাউন্ট করুন।

  2. /data এনক্রিপ্ট করা শুরু করুন

    vold.decrypt = "trigger_encryption" init.rc ট্রিগার করে, যার ফলে vold কোনো পাসওয়ার্ড ছাড়াই /data এনক্রিপ্ট করে। (কোনো পাসওয়ার্ড সেট করা নেই, কারণ এটি একটি নতুন ডিভাইস হওয়ার কথা।)

  3. মাউন্ট টিএমপিএফএস

    vold একটি tmpfs /data মাউন্ট করে ( ro.crypto.tmpfs_options থেকে tmpfs অপশনগুলো ব্যবহার করে) এবং vold.encrypt_progress প্রপার্টিটির মান 0 সেট করে। vold একটি এনক্রিপ্টেড সিস্টেম বুট করার জন্য tmpfs /data প্রস্তুত করে এবং vold.decrypt প্রপার্টিটির মান trigger_restart_min_framework সেট করে।

  4. অগ্রগতি দেখানোর জন্য কাঠামোটি উপস্থাপন করুন

    যেহেতু ডিভাইসটিতে এনক্রিপ্ট করার মতো কার্যত কোনো ডেটা নেই, তাই এনক্রিপশন খুব দ্রুত সম্পন্ন হওয়ায় প্রোগ্রেস বারটি ঘন ঘন দেখা যাবে না। প্রোগ্রেস UI সম্পর্কে আরও বিস্তারিত জানতে ‘একটি বিদ্যমান ডিভাইস এনক্রিপ্ট করুন’ দেখুন।

  5. যখন /data এনক্রিপ্ট করা হয়, তখন ফ্রেমওয়ার্কটি বন্ধ করে দিন।

    vold vold.decrypt কে trigger_default_encryption এ সেট করে, যা defaultcrypto সার্ভিসটি চালু করে। (এটি একটি ডিফল্ট এনক্রিপ্টেড ইউজারডেটা মাউন্ট করার জন্য নিচের ফ্লোটি শুরু করে।) trigger_default_encryption এনক্রিপশনের ধরন পরীক্ষা করে দেখে যে /data পাসওয়ার্ড সহ বা পাসওয়ার্ড ছাড়া এনক্রিপ্টেড কিনা। যেহেতু অ্যান্ড্রয়েড ৫.০ ডিভাইসগুলো প্রথম বুটে এনক্রিপ্টেড থাকে, তাই কোনো পাসওয়ার্ড সেট করা থাকার কথা নয়; এজন্য আমরা /data ডিক্রিপ্ট করে মাউন্ট করি।

  6. মাউন্ট /data

    এরপর init , init.rc তে সেট করা ro.crypto.tmpfs_options থেকে প্যারামিটার নিয়ে /data একটি tmpfs RAMDisk-এ মাউন্ট করে।

  7. কাঠামো শুরু করুন

    vold vold.decrypt কে trigger_restart_framework এ সেট করে, যা স্বাভাবিক বুট প্রক্রিয়া চালিয়ে যায়।

বিদ্যমান ডিভাইস এনক্রিপ্ট করুন

অ্যান্ড্রয়েড কে বা তার পূর্ববর্তী সংস্করণের কোনো এনক্রিপ্টবিহীন ডিভাইসকে এল-এ মাইগ্রেট করা হলে, সেটিকে এনক্রিপ্ট করলে এমনটাই ঘটে।

এই প্রক্রিয়াটি ব্যবহারকারী-প্রবর্তিত এবং কোডে এটিকে “ইনপ্লেস এনক্রিপশন” বলা হয়। যখন কোনো ব্যবহারকারী একটি ডিভাইস এনক্রিপ্ট করার জন্য নির্বাচন করেন, তখন ইউজার ইন্টারফেস (UI) নিশ্চিত করে যে ব্যাটারি সম্পূর্ণ চার্জ করা আছে এবং এসি অ্যাডাপ্টারটি প্লাগ ইন করা আছে, যাতে এনক্রিপশন প্রক্রিয়াটি শেষ করার জন্য পর্যাপ্ত শক্তি থাকে।

সতর্কীকরণ: এনক্রিপশন শেষ হওয়ার আগেই যদি ডিভাইসের চার্জ শেষ হয়ে যায় এবং এটি বন্ধ হয়ে যায়, তাহলে ফাইলের ডেটা আংশিকভাবে এনক্রিপ্ট করা অবস্থায় থেকে যায়। ডিভাইসটি অবশ্যই ফ্যাক্টরি রিসেট করতে হবে এবং এতে সমস্ত ডেটা হারিয়ে যাবে।

ইনপ্লেস এনক্রিপশন সক্রিয় করতে, vold আসল ব্লক ডিভাইসের প্রতিটি সেক্টর পড়ার জন্য একটি লুপ শুরু করে এবং তারপর সেটিকে ক্রিপ্টো ব্লক ডিভাইসে লেখে। vold কোনো সেক্টর পড়া এবং লেখার আগে সেটি ব্যবহৃত হচ্ছে কিনা তা পরীক্ষা করে দেখে, যা খুব কম বা কোনো ডেটা নেই এমন নতুন ডিভাইসে এনক্রিপশনকে অনেক দ্রুত করে তোলে।

ডিভাইসের অবস্থা : বুটিং চালিয়ে যাওয়ার জন্য ro.crypto.state = "unencrypted" সেট করুন এবং on nonencrypted init ট্রিগারটি কার্যকর করুন।

  1. পাসওয়ার্ড যাচাই করুন

    UI cryptfs enablecrypto inplace কমান্ডটি দিয়ে vold কল করে, যেখানে passwd হলো ব্যবহারকারীর লক স্ক্রিন পাসওয়ার্ড।

  2. কাঠামোটি ভেঙে ফেলুন

    vold ত্রুটি পরীক্ষা করে, এনক্রিপ্ট করতে না পারলে -1 রিটার্ন করে এবং লগে একটি কারণ প্রিন্ট করে। যদি এটি এনক্রিপ্ট করতে পারে, তবে এটি vold.decrypt প্রপার্টিটিকে trigger_shutdown_framework এ সেট করে। এর ফলে init.rc late_start এবং main ক্লাসের সার্ভিসগুলো বন্ধ করে দেয়।

  3. একটি ক্রিপ্টো ফুটার তৈরি করুন
  4. একটি ব্রেডক্রাম্ব ফাইল তৈরি করুন
  5. রিবুট
  6. ব্রেডক্রাম্ব ফাইল সনাক্ত করুন
  7. /data এনক্রিপ্ট করা শুরু করুন

    এরপর vold ক্রিপ্টো ম্যাপিং সেট আপ করে, যা একটি ভার্চুয়াল ক্রিপ্টো ব্লক ডিভাইস তৈরি করে। এই ভার্চুয়াল ডিভাইসটি আসল ব্লক ডিভাইসের সাথে ম্যাপ করা থাকে, কিন্তু এটি লেখার সময় প্রতিটি সেক্টর এনক্রিপ্ট করে এবং পড়ার সময় ডিক্রিপ্ট করে। তারপর vold ক্রিপ্টো মেটাডেটা তৈরি করে এবং লিখে দেয়।

  8. এনক্রিপ্ট করার সময়, tmpfs মাউন্ট করুন।

    vold একটি tmpfs /data মাউন্ট করে ( ro.crypto.tmpfs_options থেকে tmpfs অপশনগুলো ব্যবহার করে) এবং vold.encrypt_progress প্রপার্টিটির মান 0 সেট করে। vold একটি এনক্রিপ্টেড সিস্টেম বুট করার জন্য tmpfs /data প্রস্তুত করে এবং vold.decrypt প্রপার্টিটির মান trigger_restart_min_framework সেট করে।

  9. অগ্রগতি দেখানোর জন্য কাঠামোটি উপস্থাপন করুন

    trigger_restart_min_framework init.rc services-এর main ক্লাসটি চালু করতে নির্দেশ দেয়। যখন ফ্রেমওয়ার্ক দেখে যে vold.encrypt_progress মান 0 সেট করা আছে, তখন এটি প্রোগ্রেস বার UI চালু করে, যা প্রতি পাঁচ সেকেন্ডে ওই প্রপার্টিটি কোয়েরি করে এবং একটি প্রোগ্রেস বার আপডেট করে। এনক্রিপশন লুপটি প্রতিবার পার্টিশনের আরও এক শতাংশ এনক্রিপ্ট করার পর vold.encrypt_progress কে আপডেট করে।

  10. যখন /data এনক্রিপ্ট করা হয়, তখন ক্রিপ্টো ফুটার আপডেট করুন।

    যখন /data সফলভাবে এনক্রিপ্ট করা হয়, vold মেটাডেটা থেকে ENCRYPTION_IN_PROGRESS ফ্ল্যাগটি মুছে দেয়।

    ডিভাইসটি সফলভাবে আনলক হলে, পাসওয়ার্ডটি ব্যবহার করে মাস্টার কী এনক্রিপ্ট করা হয় এবং ক্রিপ্টো ফুটার আপডেট করা হয়।

    যদি কোনো কারণে রিবুট ব্যর্থ হয়, তাহলে vold তার vold.encrypt_progress প্রপার্টির মান ` error_reboot_failed সেট করে এবং ইউজার ইন্টারফেসে (UI) একটি বার্তা প্রদর্শিত হয়, যেখানে ব্যবহারকারীকে রিবুট করার জন্য একটি বাটন চাপতে বলা হয়। এমনটা কখনোই ঘটবে বলে আশা করা যায় না।

ডিফল্ট এনক্রিপশন ব্যবহার করে একটি এনক্রিপ্টেড ডিভাইস চালু করুন।

পাসওয়ার্ড ছাড়া একটি এনক্রিপ্টেড ডিভাইস চালু করলে এমনটাই ঘটে। যেহেতু অ্যান্ড্রয়েড ৫.০ ডিভাইসগুলো প্রথমবার চালুর সময় এনক্রিপ্টেড থাকে, তাই কোনো পাসওয়ার্ড সেট করা থাকে না এবং একারণেই এটি ডিফল্ট এনক্রিপশন অবস্থা।

  1. পাসওয়ার্ড ছাড়া এনক্রিপ্ট করা /data সনাক্ত করুন।

    অ্যান্ড্রয়েড ডিভাইসটি এনক্রিপ্টেড বলে শনাক্ত করা হয়েছে, কারণ /data মাউন্ট করা যাচ্ছে না এবং encryptable বা forceencrypt ফ্ল্যাগগুলোর মধ্যে একটি সেট করা আছে।

    vold vold.decrypt কে trigger_default_encryption এ সেট করে, যা defaultcrypto সার্ভিসটি চালু করে। trigger_default_encryption এনক্রিপশনের ধরন পরীক্ষা করে দেখে যে /data পাসওয়ার্ড সহ বা পাসওয়ার্ড ছাড়া এনক্রিপ্ট করা আছে কিনা।

  2. ডিক্রিপ্ট /ডেটা

    ব্লক ডিভাইসের উপর dm-crypt ডিভাইসটি তৈরি করে, যাতে ডিভাইসটি ব্যবহারের জন্য প্রস্তুত থাকে।

  3. মাউন্ট /ডেটা

    এরপর vold ডিক্রিপ্ট করা আসল /data পার্টিশনটি মাউন্ট করে এবং নতুন পার্টিশনটি প্রস্তুত করে। এটি vold.post_fs_data_done প্রপার্টিটির মান 0 সেট করে এবং তারপর vold.decrypt trigger_post_fs_data তে সেট করে। এর ফলে init.rc তার post-fs-data কমান্ডগুলো চালায়। এই কমান্ডগুলো প্রয়োজনীয় ডিরেক্টরি বা লিঙ্ক তৈরি করে এবং তারপর vold.post_fs_data_done মান 1 সেট করে দেয়।

    vold যখনই ওই প্রপার্টিতে 1 দেখতে পায়, তখন এটি vold.decrypt প্রপার্টিটিকে trigger_restart_framework. এর ফলে init.rc আবার main ক্লাসের সার্ভিসগুলো চালু করে এবং বুট হওয়ার পর প্রথমবারের মতো late_start ক্লাসের সার্ভিসগুলোও চালু করে।

  4. কাঠামো শুরু করুন

    এখন ফ্রেমওয়ার্কটি ডিক্রিপ্ট করা /data ব্যবহার করে তার সমস্ত পরিষেবা চালু করে এবং সিস্টেমটি ব্যবহারের জন্য প্রস্তুত হয়ে যায়।

ডিফল্ট এনক্রিপশন ছাড়া একটি এনক্রিপ্টেড ডিভাইস চালু করুন

পাসওয়ার্ড সেট করা কোনো এনক্রিপ্টেড ডিভাইস চালু করলে এমনটাই ঘটে। ডিভাইসটির পাসওয়ার্ড পিন, প্যাটার্ন বা পাসওয়ার্ড হতে পারে।

  1. পাসওয়ার্ড দিয়ে এনক্রিপ্ট করা ডিভাইস সনাক্ত করুন।

    অ্যান্ড্রয়েড ডিভাইসটি এনক্রিপ্টেড তা শনাক্ত করুন, কারণ ro.crypto.state = "encrypted" ফ্ল্যাগটি রয়েছে।

    /data পাসওয়ার্ড দিয়ে এনক্রিপ্ট করা থাকায় vold vold.decrypt কে trigger_restart_min_framework এ সেট করে।

  2. মাউন্ট টিএমপিএফএস

    init.rc থেকে পাঠানো প্যারামিটার ব্যবহার করে /data জন্য প্রদত্ত প্রাথমিক মাউন্ট অপশনগুলো সংরক্ষণ করতে init পাঁচটি প্রপার্টি সেট করে। 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 (0x দ্বারা পূর্বে যুক্ত ৮-অঙ্কের ASCII হেক্স নম্বর)
  3. পাসওয়ার্ডের জন্য অনুরোধ করতে ফ্রেমওয়ার্ক শুরু করুন

    ফ্রেমওয়ার্কটি চালু হয়ে দেখে যে vold.decrypt trigger_restart_min_framework এ সেট করা আছে। এটি ফ্রেমওয়ার্ককে জানিয়ে দেয় যে এটি একটি tmpfs /data ডিস্কে বুট করছে এবং এর ব্যবহারকারীর পাসওয়ার্ড প্রয়োজন।

    তবে, প্রথমে এটিকে নিশ্চিত করতে হবে যে ডিস্কটি সঠিকভাবে এনক্রিপ্ট করা হয়েছে। এটি vold কে cryptfs cryptocomplete কমান্ডটি পাঠায়। এনক্রিপশন সফলভাবে সম্পন্ন হলে vold ০ রিটার্ন করে, অভ্যন্তরীণ ত্রুটির ক্ষেত্রে -১, অথবা এনক্রিপশন সফলভাবে সম্পন্ন না হলে -২ রিটার্ন করে। vold ক্রিপ্টো মেটাডেটাতে CRYPTO_ENCRYPTION_IN_PROGRESS ফ্ল্যাগটি দেখে এটি নির্ধারণ করে। যদি এটি সেট করা থাকে, তাহলে এনক্রিপশন প্রক্রিয়াটি বাধাগ্রস্ত হয়েছে এবং ডিভাইসে কোনো ব্যবহারযোগ্য ডেটা নেই। যদি vold কোনো ত্রুটি রিটার্ন করে, তাহলে UI-তে ব্যবহারকারীকে ডিভাইসটি রিবুট এবং ফ্যাক্টরি রিসেট করার জন্য একটি বার্তা দেখানো উচিত এবং তা করার জন্য ব্যবহারকারীকে একটি বাটন দেওয়া উচিত।

  4. পাসওয়ার্ড দিয়ে ডেটা ডিক্রিপ্ট করুন

    একবার cryptfs cryptocomplete সফল হলে, ফ্রেমওয়ার্কটি ডিস্ক পাসওয়ার্ড চেয়ে একটি UI প্রদর্শন করে। UI-টি vold cryptfs checkpw কমান্ড পাঠিয়ে পাসওয়ার্ডটি যাচাই করে। যদি পাসওয়ার্ডটি সঠিক হয় (যা একটি অস্থায়ী স্থানে ডিক্রিপ্ট করা /data সফলভাবে মাউন্ট করে এবং তারপর আনমাউন্ট করার মাধ্যমে নিশ্চিত করা হয়), vold ডিক্রিপ্ট করা ব্লক ডিভাইসের নামটি ro.crypto.fs_crypto_blkdev প্রপার্টিতে সংরক্ষণ করে এবং UI-তে স্ট্যাটাস 0 ফেরত পাঠায়। যদি পাসওয়ার্ডটি ভুল হয়, তবে এটি UI-তে -1 ফেরত পাঠায়।

  5. ফ্রেমওয়ার্ক বন্ধ করুন

    UI একটি ক্রিপ্টো বুট গ্রাফিক প্রদর্শন করে এবং তারপর cryptfs restart কমান্ড দিয়ে vold কল করে। vold তার vold.decrypt প্রপার্টিকে ` trigger_reset_main এ সেট করে, যার ফলে init.rc class_reset main চালায়। এটি `main` ক্লাসের সমস্ত সার্ভিস বন্ধ করে দেয়, যার ফলে `tmpfs /data আনমাউন্ট করা যায়।

  6. মাউন্ট /data

    এরপর vold ডিক্রিপ্ট করা আসল /data পার্টিশনটি মাউন্ট করে এবং নতুন পার্টিশনটি প্রস্তুত করে (যেটি হয়তো কখনোই প্রস্তুত হতো না যদি এটি wipe অপশন দিয়ে এনক্রিপ্ট করা থাকত, যা প্রথম রিলিজে সমর্থিত নয়)। এটি vold.post_fs_data_done প্রপার্টিটির মান 0 সেট করে এবং তারপর vold.decrypt এর মান trigger_post_fs_data সেট করে। এর ফলে init.rc তার post-fs-data কমান্ডগুলো চালায়। এগুলো প্রয়োজনীয় ডিরেক্টরি বা লিঙ্ক তৈরি করে এবং তারপর vold.post_fs_data_done এর মান 1 সেট করে। যখন vold ওই প্রপার্টিতে 1 দেখতে পায়, তখন এটি vold.decrypt প্রপার্টিটির মান trigger_restart_framework সেট করে। এর ফলে init.rc আবার main ক্লাসের সার্ভিসগুলো চালু করে এবং বুট হওয়ার পর প্রথমবারের মতো late_start ক্লাসের সার্ভিসগুলোও চালু করে।

  7. সম্পূর্ণ কাঠামো শুরু করুন

    এখন ফ্রেমওয়ার্কটি ডিক্রিপ্ট করা /data ফাইলসিস্টেম ব্যবহার করে তার সমস্ত পরিষেবা বুট করে এবং সিস্টেমটি ব্যবহারের জন্য প্রস্তুত হয়ে যায়।

ব্যর্থতা

যে ডিভাইসটি ডিক্রিপ্ট করতে ব্যর্থ হয়, তাতে কয়েকটি কারণে ত্রুটি থাকতে পারে। ডিভাইসটি বুট করার জন্য স্বাভাবিক ধাপগুলো অনুসরণ করে চালু হয়:

  1. পাসওয়ার্ড দিয়ে এনক্রিপ্ট করা ডিভাইস সনাক্ত করুন।
  2. মাউন্ট টিএমপিএফএস
  3. পাসওয়ার্ডের জন্য অনুরোধ করতে ফ্রেমওয়ার্ক শুরু করুন

কিন্তু ফ্রেমওয়ার্কটি খোলার পর ডিভাইসটিতে কিছু ত্রুটি দেখা দিতে পারে:

  • পাসওয়ার্ড মিলেছে কিন্তু ডেটা ডিক্রিপ্ট করা যাচ্ছে না।
  • ব্যবহারকারী ৩০ বার ভুল পাসওয়ার্ড দিয়েছেন

যদি এই ত্রুটিগুলি সমাধান না করা হয়, তবে ব্যবহারকারীকে ফ্যাক্টরি ওয়াইপ করতে বলুন :

এনক্রিপশন প্রক্রিয়ার সময় vold যদি কোনো ত্রুটি শনাক্ত করে, এবং যদি তখনও কোনো ডেটা নষ্ট না হয়ে থাকে ও ফ্রেমওয়ার্কটি চালু থাকে, তাহলে vold তার vold.encrypt_progress প্রপার্টির মান error_not_encrypted এ সেট করে দেয়। ইউজার ইন্টারফেস (UI) ব্যবহারকারীকে রিবুট করার জন্য অনুরোধ করে এবং সতর্ক করে যে এনক্রিপশন প্রক্রিয়াটি কখনোই শুরু হয়নি। যদি ফ্রেমওয়ার্কটি বন্ধ হয়ে যাওয়ার পরে, কিন্তু প্রোগ্রেস বার UI চালু হওয়ার আগে ত্রুটিটি ঘটে, vold সিস্টেমটি রিবুট করে। যদি রিবুট ব্যর্থ হয়, তবে এটি vold.encrypt_progress এর error_shutting_down এ সেট করে এবং -1 রিটার্ন করে; কিন্তু ত্রুটিটি ধরার মতো কিছু থাকবে না। এমনটা ঘটার কথা নয়।

এনক্রিপশন প্রক্রিয়ার সময় vold কোনো ত্রুটি শনাক্ত করলে, এটি vold.encrypt_progress কে error_partially_encrypted এ সেট করে এবং -1 রিটার্ন করে। এরপর UI-তে এনক্রিপশন ব্যর্থ হওয়ার একটি বার্তা প্রদর্শিত হবে এবং ব্যবহারকারীকে ডিভাইসটি ফ্যাক্টরি রিসেট করার জন্য একটি বাটন দেওয়া হবে।

এনক্রিপ্ট করা কী সংরক্ষণ করুন

এনক্রিপ্টেড কী-টি ক্রিপ্টো মেটাডেটাতে সংরক্ষিত থাকে। ট্রাস্টেড এক্সিকিউশন এনভায়রনমেন্ট (TEE)-এর সাইনিং ক্ষমতা ব্যবহার করে হার্ডওয়্যার ব্যাকং বাস্তবায়ন করা হয়। পূর্বে, আমরা ব্যবহারকারীর পাসওয়ার্ড এবং সংরক্ষিত সল্ট-এর উপর স্ক্রিপ্ট (scrypt) প্রয়োগ করে তৈরি করা একটি কী দিয়ে মাস্টার কী-টি এনক্রিপ্ট করেছিলাম। অফ-বক্স অ্যাটাকের বিরুদ্ধে কী-টিকে সুরক্ষিত করার জন্য, আমরা প্রাপ্ত কী-টিকে একটি সংরক্ষিত TEE কী দিয়ে সাইন করে এই অ্যালগরিদমটিকে আরও প্রসারিত করি। এরপর প্রাপ্ত সিগনেচারটিকে স্ক্রিপ্ট (scrypt)-এর আরও একটি প্রয়োগের মাধ্যমে একটি উপযুক্ত দৈর্ঘ্যের কী-তে রূপান্তরিত করা হয়। এই কী-টি তারপর মাস্টার কী-কে এনক্রিপ্ট এবং ডিক্রিপ্ট করতে ব্যবহৃত হয়। এই কী-টি সংরক্ষণ করতে:

  1. র‍্যান্ডম ১৬-বাইট ডিস্ক এনক্রিপশন কী (DEK) এবং ১৬-বাইট সল্ট তৈরি করুন।
  2. ব্যবহারকারীর পাসওয়ার্ড এবং সল্ট-এর উপর স্ক্রিপ্ট (scrypt) প্রয়োগ করে ৩২-বাইটের অন্তর্বর্তী কী ১ (IK1) তৈরি করুন।
  3. হার্ডওয়্যার-বাউন্ড প্রাইভেট কী (HBK)-এর আকার অনুযায়ী IK1-কে শূন্য বাইট দিয়ে প্যাড করুন। নির্দিষ্টভাবে, আমরা এভাবে প্যাড করি: 00 || IK1 || 00..00; একটি শূন্য বাইট, ৩২টি IK1 বাইট, ২২৩টি শূন্য বাইট।
  4. ২৫৬-বাইটের IK2 তৈরি করতে প্যাডেড IK1-কে HBK দিয়ে স্বাক্ষর করুন।
  5. ৩২-বাইটের IK3 তৈরি করতে IK2 এবং সল্ট (ধাপ ২-এর মতো একই সল্ট) এর উপর স্ক্রিপ্ট প্রয়োগ করুন।
  6. IK3-এর প্রথম ১৬ বাইটকে KEK এবং শেষ ১৬ বাইটকে IV হিসেবে ব্যবহার করুন।
  7. KEK কী এবং IV ইনিশিয়ালাইজেশন ভেক্টর ব্যবহার করে AES_CBC পদ্ধতিতে DEK এনক্রিপ্ট করুন।

পাসওয়ার্ড পরিবর্তন করুন

যখন কোনো ব্যবহারকারী সেটিংসে তাদের পাসওয়ার্ড পরিবর্তন বা মুছে ফেলার সিদ্ধান্ত নেন, তখন UI, vold কে cryptfs changepw কমান্ডটি পাঠায় এবং vold নতুন পাসওয়ার্ড দিয়ে ডিস্ক মাস্টার কী-টি পুনরায় এনক্রিপ্ট করে।

এনক্রিপশন বৈশিষ্ট্য

vold এবং init প্রোপার্টি সেট করার মাধ্যমে একে অপরের সাথে যোগাযোগ করে। এখানে এনক্রিপশনের জন্য উপলব্ধ প্রোপার্টিগুলোর একটি তালিকা দেওয়া হলো।

ভোল্ড সম্পত্তি

সম্পত্তি বর্ণনা
vold.decrypt trigger_encryption পাসওয়ার্ড ছাড়া ড্রাইভটি এনক্রিপ্ট করুন।
vold.decrypt trigger_default_encryption ড্রাইভটি পাসওয়ার্ড ছাড়া এনক্রিপ্ট করা আছে কিনা তা পরীক্ষা করুন। যদি থাকে, তবে এটিকে ডিক্রিপ্ট করে মাউন্ট করুন, অন্যথায় vold.decrypt কে trigger_restart_min_framework-এ সেট করুন।
vold.decrypt trigger_reset_main ডিস্ক পাসওয়ার্ড চাওয়ার UI বন্ধ করার জন্য vold দ্বারা সেট করা হয়েছে।
vold.decrypt trigger_post_fs_data ভোল্ড দ্বারা /data প্রয়োজনীয় ডিরেক্টরি ইত্যাদি দিয়ে প্রস্তুত করার জন্য সেট করা হয়েছে।
vold.decrypt trigger_restart_framework আসল ফ্রেমওয়ার্ক এবং সমস্ত পরিষেবা চালু করার জন্য ভোল্ড দ্বারা সেট করা হয়েছে।
vold.decrypt trigger_shutdown_framework এনক্রিপশন শুরু করার জন্য সম্পূর্ণ ফ্রেমওয়ার্কটি বন্ধ করতে ভোল্ড দ্বারা সেট করা হয়েছে।
vold.decrypt trigger_restart_min_framework ro.crypto.state এর মানের উপর নির্ভর করে, এনক্রিপশনের জন্য প্রোগ্রেস বার UI চালু করতে বা পাসওয়ার্ড চাইতে vold দ্বারা এটি সেট করা হয়।
vold.encrypt_progress ফ্রেমওয়ার্কটি চালু হওয়ার সময়, এই প্রপার্টিটি সেট করা থাকলে, প্রোগ্রেস বার UI মোডে প্রবেশ করুন।
vold.encrypt_progress 0 to 100 প্রোগ্রেস বার UI-তে সেট করা শতাংশের মানটি প্রদর্শিত হওয়া উচিত।
vold.encrypt_progress error_partially_encrypted প্রোগ্রেস বার UI-তে এনক্রিপশন ব্যর্থ হওয়ার একটি বার্তা প্রদর্শন করা উচিত এবং ব্যবহারকারীকে ডিভাইসটি ফ্যাক্টরি রিসেট করার একটি বিকল্প দেওয়া উচিত।
vold.encrypt_progress error_reboot_failed প্রোগ্রেস বার UI-তে 'এনক্রিপশন সম্পন্ন হয়েছে' লেখা একটি বার্তা প্রদর্শিত হওয়া উচিত এবং ব্যবহারকারীকে ডিভাইসটি রিবুট করার জন্য একটি বাটন দেওয়া উচিত। এই ত্রুটিটি ঘটা প্রত্যাশিত নয়।
vold.encrypt_progress error_not_encrypted প্রোগ্রেস বার UI-তে একটি বার্তা প্রদর্শিত হওয়া উচিত, যেখানে বলা থাকবে যে একটি ত্রুটি ঘটেছে, কোনো ডেটা এনক্রিপ্ট বা হারিয়ে যায়নি, এবং ব্যবহারকারীকে সিস্টেম রিবুট করার জন্য একটি বাটন দেওয়া হবে।
vold.encrypt_progress error_shutting_down প্রোগ্রেস বার UI চালু নেই, তাই এই ত্রুটির ক্ষেত্রে কে সাড়া দেবে তা স্পষ্ট নয়। আর এমনটা কখনোই হওয়া উচিত নয়।
vold.post_fs_data_done 0 vold.decrypt trigger_post_fs_data তে সেট করার ঠিক আগে vold দ্বারা এটি সেট করা হয়।
vold.post_fs_data_done 1 init.rc দ্বারা অথবা post-fs-data টাস্কটি শেষ হওয়ার ঠিক পরেই সেট করা হয় init.rc

প্রাথমিক বৈশিষ্ট্য

সম্পত্তি বর্ণনা
ro.crypto.fs_crypto_blkdev পরবর্তীতে vold কমান্ড restart দ্বারা ব্যবহারের জন্য vold checkpw কমান্ডের মাধ্যমে সেট করা হয়।
ro.crypto.state unencrypted এই সিস্টেমটি একটি এনক্রিপ্টবিহীন /data ro.crypto.state encrypted সহ চলছে তা বোঝাতে init দ্বারা সেট করা হয়েছে। এই সিস্টেমটি একটি এনক্রিপ্টেড /data সহ চলছে তা বোঝাতে init দ্বারা সেট করা হয়েছে।

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

init.rc থেকে পাঠানো প্যারামিটার ব্যবহার করে যখন init /data মাউন্ট করার চেষ্টা করে, তখন এই পাঁচটি প্রপার্টি সেট করা হয়। vold ক্রিপ্টো ম্যাপিং সেটআপ করার জন্য এগুলো ব্যবহার করে।
ro.crypto.tmpfs_options init.rc দ্বারা সেট করা হয় সেই অপশনগুলো, যা init 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