কীমাস্টার ১-এ, সমস্ত কীমাস্টার কী ক্রিপ্টোগ্রাফিকভাবে ডিভাইসের রুট অফ ট্রাস্ট (Root of Trust) বা ভেরিফায়েড বুট কী (Verified Boot key)-এর সাথে আবদ্ধ ছিল। কীমাস্টার ২ এবং ৩-এ, সমস্ত কী অপারেটিং সিস্টেম এবং সিস্টেম ইমেজের প্যাচ লেভেলের সাথেও আবদ্ধ থাকে। এটি নিশ্চিত করে যে, কোনো আক্রমণকারী যদি সিস্টেম বা TEE সফটওয়্যারের পুরোনো সংস্করণে কোনো দুর্বলতা খুঁজে পায়, তবে সে ডিভাইসটিকে সেই দুর্বল সংস্করণে ফিরিয়ে নিয়ে যেতে এবং নতুন সংস্করণ দিয়ে তৈরি কী ব্যবহার করতে পারবে না। এছাড়াও, যখন একটি নির্দিষ্ট সংস্করণ এবং প্যাচ লেভেলের কী এমন কোনো ডিভাইসে ব্যবহার করা হয় যা নতুন সংস্করণ বা প্যাচ লেভেলে আপগ্রেড করা হয়েছে, তখন ব্যবহারের আগে কী-টি আপগ্রেড হয়ে যায় এবং কী-টির পূর্ববর্তী সংস্করণটি অকার্যকর হয়ে পড়ে। এইভাবে, ডিভাইসটি আপগ্রেড হওয়ার সাথে সাথে কী-গুলোও ডিভাইসের সাথে সাথে এগিয়ে যায়, কিন্তু ডিভাইসটিকে পূর্ববর্তী কোনো সংস্করণে ফিরিয়ে নিয়ে গেলে কী-গুলো অব্যবহারযোগ্য হয়ে পড়ে।
Treble-এর মডিউলার কাঠামোকে সমর্থন করতে এবং system.img ও boot.img-এর মধ্যকার বন্ধন ভাঙতে, Keymaster 4 প্রতিটি পার্টিশনের জন্য আলাদা প্যাচ লেভেল রাখার উদ্দেশ্যে কী ভার্সন বাইন্ডিং মডেলটি পরিবর্তন করেছে। এর ফলে প্রতিটি পার্টিশন স্বাধীনভাবে আপডেট করা যায় এবং একই সাথে রোলব্যাক সুরক্ষাও বজায় থাকে।
এই ভার্সন বাইন্ডিং বাস্তবায়ন করতে, KeyMint ট্রাস্টেড অ্যাপ (TA)-এর বর্তমান OS ভার্সন ও প্যাচ লেভেলগুলো নিরাপদে গ্রহণ করার এবং প্রাপ্ত তথ্য চলমান সিস্টেমের সমস্ত তথ্যের সাথে মিলে যায় তা নিশ্চিত করার একটি উপায় প্রয়োজন।
- অ্যান্ড্রয়েড ভেরিফাইড বুট (AVB) যুক্ত ডিভাইসগুলো সমস্ত প্যাচ লেভেল এবং সিস্টেম ভার্সন vbmeta-তে রাখতে পারে, যাতে বুটলোডার সেগুলো Keymaster-কে সরবরাহ করতে পারে। চেইনড পার্টিশনের ক্ষেত্রে, পার্টিশনের ভার্সন তথ্য চেইনড vbmeta-তে থাকে। সাধারণত, ভার্সন তথ্য সেই
vbmeta structথাকা উচিত, যা একটি নির্দিষ্ট পার্টিশনের জন্য ভেরিফিকেশন ডেটা (হ্যাশ বা হ্যাশট্রি) ধারণ করে। - যেসব ডিভাইসে AVB নেই:
- ভেরিফাইড বুট ইমপ্লিমেন্টেশনগুলোকে বুটলোডারের কাছে ভার্সন মেটাডেটার একটি হ্যাশ সরবরাহ করতে হয়, যাতে বুটলোডার সেই হ্যাশটি কীমাস্টারের কাছে পৌঁছে দিতে পারে।
-
boot.imgহেডারে প্যাচ লেভেল সংরক্ষণ করা চালিয়ে যেতে পারে। -
system.imgরিড-অনলি প্রোপার্টিতে প্যাচ লেভেল এবং ওএস ভার্সন সংরক্ষণ করা চালিয়ে যেতে পারে। -
vendor.imgro.vendor.build.version.security_patchএকটি রিড-অনলি প্রপার্টিতে প্যাচ লেভেল সংরক্ষণ করে। - বুটলোডার, ভেরিফায়েড বুট দ্বারা যাচাইকৃত সমস্ত ডেটার একটি হ্যাশ কীমাস্টারকে প্রদান করতে পারে।
- অ্যান্ড্রয়েড ৯-এ, নিম্নলিখিত পার্টিশনগুলির সংস্করণ তথ্য সরবরাহ করতে নিচের ট্যাগগুলি ব্যবহার করুন:
-
VENDOR_PATCH_LEVEL:vendorপার্টিশন -
BOOT_PATCH_LEVEL:bootপার্টিশন -
OS_PATCH_LEVELএবংOS_VERSION:systemপার্টিশন। (OS_VERSIONboot.imgহেডার থেকে সরিয়ে দেওয়া হয়।)
-
- Keymaster ইমপ্লিমেন্টেশনগুলোর উচিত সমস্ত প্যাচ লেভেলকে স্বাধীনভাবে বিবেচনা করা। কী-গুলো তখনই ব্যবহারযোগ্য হয়, যখন একটি কী-এর সাথে যুক্ত ভ্যালুগুলোর সাথে সমস্ত ভার্সন তথ্য মিলে যায়, এবং প্রয়োজনে
IKeymaster::upgradeDevice()একটি উচ্চতর প্যাচ লেভেলে রোল করে।
HAL পরিবর্তন
ভার্সন বাইন্ডিং এবং ভার্সন অ্যাটেস্টেশন সমর্থন করার জন্য, অ্যান্ড্রয়েড ৭.১-এ Tag::OS_VERSION ও Tag::OS_PATCHLEVEL এবং configure ও upgradeKey মেথড যুক্ত করা হয়েছে। Keymaster 2+ ইমপ্লিমেন্টেশনগুলো দ্বারা সমস্ত নতুন তৈরি (বা আপডেট করা) কী-তে এই ভার্সন ট্যাগগুলো স্বয়ংক্রিয়ভাবে যুক্ত হয়ে যায়। এছাড়াও, এমন কোনো কী ব্যবহার করার চেষ্টা করা হলে, যার ওএস ভার্সন বা প্যাচ লেভেল যথাক্রমে বর্তমান সিস্টেমের ওএস ভার্সন বা প্যাচ লেভেলের সাথে মেলে না, তা ErrorCode::KEY_REQUIRES_UPGRADE দেখিয়ে বাতিল করে দেওয়া হয়।
Tag::OS_VERSION হলো একটি UINT ভ্যালু যা একটি অ্যান্ড্রয়েড সিস্টেম ভার্সনের মেজর, মাইনর এবং সাব-মাইনর অংশকে MMmmss আকারে প্রকাশ করে, যেখানে MM হলো মেজর ভার্সন, mm হলো মাইনর ভার্সন এবং ss হলো সাব-মাইনর ভার্সন। উদাহরণস্বরূপ, 6.1.2-কে 060102 হিসেবে প্রকাশ করা হবে।
Tag::OS_PATCHLEVEL হলো একটি UINT ভ্যালু যা সিস্টেমের সর্বশেষ আপডেটের বছর এবং মাসকে YYYYMM আকারে প্রকাশ করে, যেখানে YYYY হলো চার-অঙ্কের বছর এবং MM হলো দুই-অঙ্কের মাস। উদাহরণস্বরূপ, মার্চ ২০১৬-কে 201603 হিসাবে প্রকাশ করা হবে।
আপগ্রেডকী
সিস্টেম ইমেজের নতুন OS ভার্সন এবং প্যাচ লেভেলে কী-গুলোকে আপগ্রেড করার সুযোগ দিতে, Android 7.1 HAL-এ upgradeKey মেথডটি যোগ করেছে:
কীমাস্টার ৩
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams)
generates(ErrorCode error, vec upgradedKeyBlob);
কীমাস্টার ২
keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
const keymaster_key_blob_t* key_to_upgrade,
const keymaster_key_param_set_t* upgrade_params,
keymaster_key_blob_t* upgraded_key);
-
devহল ডিভাইস কাঠামো -
keyBlobToUpgradeহলো সেই কী, যেটিকে আপগ্রেড করা প্রয়োজন। -
upgradeParamsহলো কী আপগ্রেড করার জন্য প্রয়োজনীয় প্যারামিটার। এর মধ্যে রয়েছেTag::APPLICATION_IDএবংTag::APPLICATION_DATA, যা কী ব্লব ডিক্রিপ্ট করার জন্য অপরিহার্য, যদি তৈরির সময় এগুলো সরবরাহ করা হয়ে থাকে। -
upgradedKeyBlobহলো আউটপুট প্যারামিটার, যা নতুন কী ব্লবটি ফেরত দিতে ব্যবহৃত হয়।
যদি এমন কোনো কী ব্লব দিয়ে upgradeKey কল করা হয় যা পার্স করা যায় না বা অন্য কোনোভাবে অবৈধ, তাহলে এটি ErrorCode::INVALID_KEY_BLOB রিটার্ন করে। যদি এমন কোনো কী দিয়ে এটি কল করা হয় যার প্যাচ লেভেল বর্তমান সিস্টেম ভ্যালুর চেয়ে বেশি, তাহলে এটি ErrorCode::INVALID_ARGUMENT রিটার্ন করে। যদি এমন কোনো কী দিয়ে এটি কল করা হয় যার OS ভার্সন বর্তমান সিস্টেম ভ্যালুর চেয়ে বেশি, এবং সিস্টেম ভ্যালুটি নন-জিরো হয়, তাহলে এটি ErrorCode::INVALID_ARGUMENT রিটার্ন করে। নন-জিরো থেকে জিরোতে OS ভার্সন আপগ্রেড করার অনুমতি আছে। সুরক্ষিত জগতের সাথে যোগাযোগের ক্ষেত্রে কোনো ত্রুটি ঘটলে, এটি একটি উপযুক্ত এরর ভ্যালু রিটার্ন করে (উদাহরণস্বরূপ, ErrorCode::SECURE_HW_ACCESS_DENIED , ErrorCode::SECURE_HW_BUSY )। অন্যথায়, এটি ErrorCode::OK রিটার্ন করে এবং upgradedKeyBlob এ একটি নতুন কী ব্লব রিটার্ন করে।
upgradeKey কল করার পরেও keyBlobToUpgrade বৈধ থাকে, এবং ডিভাইসটি ডাউনগ্রেড করা হলেও তাত্ত্বিকভাবে এটি আবার ব্যবহার করা যেতে পারে। বাস্তবে, কীস্টোর সাধারণত upgradeKey কল করার কিছুক্ষণ পরেই keyBlobToUpgrade ব্লবটির উপর deleteKey কল করে। যদি keyBlobToUpgrade Tag::ROLLBACK_RESISTANT থাকে, তাহলে upgradedKeyBlob সেটি থাকা উচিত (এবং এটি রোলব্যাক-প্রতিরোধী হওয়া উচিত)।
নিরাপদ কনফিগারেশন
ভার্সন বাইন্ডিং বাস্তবায়ন করতে, কীমাস্টার টিএ-এর বর্তমান ওএস ভার্সন ও প্যাচ লেভেল (ভার্সন সংক্রান্ত তথ্য) নিরাপদে গ্রহণ করার এবং প্রাপ্ত তথ্য যেন চলমান সিস্টেমের তথ্যের সাথে দৃঢ়ভাবে মিলে যায়, তা নিশ্চিত করার একটি উপায় প্রয়োজন।
TA-তে ভার্সন তথ্যের নিরাপদ সরবরাহ নিশ্চিত করতে, বুট ইমেজ হেডারে একটি OS_VERSION ফিল্ড যোগ করা হয়েছে। বুট ইমেজ বিল্ড স্ক্রিপ্ট স্বয়ংক্রিয়ভাবে এই ফিল্ডটি পূরণ করে। OEM এবং Keymaster TA বাস্তবায়নকারীদের একসাথে কাজ করে ডিভাইস বুটলোডারগুলো এমনভাবে পরিবর্তন করতে হবে, যাতে অ-সুরক্ষিত সিস্টেমটি বুট হওয়ার আগেই বুট ইমেজ থেকে ভার্সন তথ্য বের করে TA-তে পাঠানো যায়। এটি নিশ্চিত করে যে আক্রমণকারীরা TA-তে ভার্সন তথ্য সরবরাহে হস্তক্ষেপ করতে পারবে না।
সিস্টেম ইমেজের ভার্সন তথ্য যেন বুট ইমেজের ভার্সন তথ্যের সমান হয়, তা নিশ্চিত করাও প্রয়োজন। সেই লক্ষ্যে, Keymaster HAL-এ configure মেথডটি যোগ করা হয়েছে:
keymaster_error_t (*configure)(const struct keymaster2_device* dev, const keymaster_key_param_set_t* params);
params আর্গুমেন্টটিতে Tag::OS_VERSION এবং Tag::OS_PATCHLEVEL থাকে। `keymaster2` ক্লায়েন্টরা `HAL` খোলার পর, কিন্তু অন্য কোনো মেথড কল করার আগে এই মেথডটি কল করে। `configure`-এর আগে যদি অন্য কোনো মেথড কল করা হয়, তাহলে `TA` ` ErrorCode::KEYMASTER_NOT_CONFIGURED রিটার্ন করে।
ডিভাইসটি বুট করার পর প্রথমবার যখন configure কল করা হয়, তখন এটি যাচাই করে দেখবে যে প্রদত্ত ভার্সন তথ্য বুটলোডার দ্বারা প্রদত্ত তথ্যের সাথে মেলে কিনা। যদি ভার্সন তথ্য না মেলে, configure ErrorCode::INVALID_ARGUMENT রিটার্ন করে, এবং অন্যান্য সমস্ত Keymaster মেথড ErrorCode::KEYMASTER_NOT_CONFIGURED রিটার্ন করতে থাকে। যদি তথ্য মিলে যায়, configure ErrorCode::OK রিটার্ন করে, এবং অন্যান্য Keymaster মেথডগুলো স্বাভাবিকভাবে কাজ করা শুরু করে।
পরবর্তী configure কলগুলো প্রথম কলের মতোই একই মান ফেরত দেয় এবং কীমাস্টারের অবস্থার কোনো পরিবর্তন করে না।
যেহেতু configure সেই সিস্টেম দ্বারাই কল করা হয় যার বিষয়বস্তু যাচাই করার জন্য এটি ব্যবহৃত হয়, তাই একজন আক্রমণকারীর জন্য সিস্টেম ইমেজকে কম্প্রোমাইজ করে তাকে এমন ভার্সন তথ্য সরবরাহ করতে বাধ্য করার একটি সংকীর্ণ সুযোগ থাকে যা বুট ইমেজের সাথে মেলে, কিন্তু সেটি সিস্টেমের প্রকৃত ভার্সন নয়। বুট ইমেজ যাচাইকরণ, সিস্টেম ইমেজের বিষয়বস্তুর dm-verity দ্বারা যাচাইকরণ, এবং সিস্টেম বুট হওয়ার একেবারে শুরুতে configure কমান্ডটি কল হওয়ার বিষয়টি—এই সম্মিলিত কারণগুলো এই সুযোগকে কাজে লাগানো কঠিন করে তুলবে।