কী এবং আইডি প্রত্যয়ন

কীস্টোর একটি নিয়ন্ত্রিত উপায়ে ক্রিপ্টোগ্রাফিক কী তৈরি, সঞ্চয় এবং ব্যবহার করার জন্য আরও নিরাপদ স্থান প্রদান করে। যখন হার্ডওয়্যার-ব্যাকড কী স্টোরেজ পাওয়া যায় এবং ব্যবহার করা হয়, তখন মূল উপাদান ডিভাইস থেকে নিষ্কাশনের বিরুদ্ধে আরও নিরাপদ, এবং কীমাস্টার এমন বিধিনিষেধ প্রয়োগ করে যেগুলি বিকৃত করা কঠিন।

এটি শুধুমাত্র সত্য, তবে, যদি কী-স্টোর কীগুলি হার্ডওয়্যার-ব্যাকড স্টোরেজে বলে জানা যায়। Keymaster 1-এ, অ্যাপস বা রিমোট সার্ভারের জন্য এই ঘটনাটি ছিল কিনা তা নির্ভরযোগ্যভাবে যাচাই করার কোনো উপায় ছিল না। কীস্টোর ডেমন উপলব্ধ কীমাস্টার HAL লোড করেছে এবং কীগুলির হার্ডওয়্যার ব্যাকিংয়ের ক্ষেত্রে HAL যা বলেছে তা বিশ্বাস করে।

এর প্রতিকারের জন্য, Keymaster Android 7.0 (Keymaster 2) একী প্রত্যয়ন এবং Android 8.0 (Keymaster 3) এ আইডি প্রত্যয়ন চালু করেছে।

কী প্রত্যয়নের লক্ষ্য হল একটি অপ্রতিসম কী জোড়া হার্ডওয়্যার-সমর্থিত কিনা, কীটির বৈশিষ্ট্যগুলি কী এবং এর ব্যবহারে কোন সীমাবদ্ধতাগুলি প্রয়োগ করা হয়েছে তা দৃঢ়ভাবে নির্ধারণ করার একটি উপায় প্রদান করা।

আইডি প্রত্যয়ন ডিভাইসটিকে তার হার্ডওয়্যার শনাক্তকারীর প্রমাণ প্রদান করতে দেয়, যেমন সিরিয়াল নম্বর বা IMEI।

মূল প্রত্যয়ন

মূল প্রত্যয়ন সমর্থন করার জন্য, Android 7.1 HAL-তে ট্যাগ, টাইপ এবং পদ্ধতির একটি সেট প্রবর্তন করেছে।

ট্যাগ

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

টাইপ

কীমাস্টার 2 এবং নীচে

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

AttestKey পদ্ধতি

কীমাস্টার 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

কীমাস্টার 2 এবং নীচে

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev হল কীমাস্টার ডিভাইস স্ট্রাকচার।
  • keyToAttest হল generateKey থেকে ফিরে আসা কী ব্লব যার জন্য প্রত্যয়ন তৈরি করা হবে।
  • attestParams হল প্রত্যয়নের জন্য প্রয়োজনীয় যে কোনো পরামিতির একটি তালিকা। এর মধ্যে রয়েছে Tag::ATTESTATION_CHALLENGE এবং সম্ভবত Tag::RESET_SINCE_ID_ROTATION , সেইসাথে Tag::APPLICATION_ID এবং Tag::APPLICATION_DATA । পরবর্তী দুটি কী ব্লব ডিক্রিপ্ট করার জন্য প্রয়োজনীয় যদি সেগুলি কী তৈরির সময় নির্দিষ্ট করা হয়।
  • certChain হল আউটপুট প্যারামিটার, যা শংসাপত্রের একটি অ্যারে প্রদান করে। এন্ট্রি 0 হল প্রত্যয়ন শংসাপত্র, যার অর্থ এটি keyToAttest থেকে কীটি প্রত্যয়িত করে এবং এতে প্রত্যয়ন এক্সটেনশন রয়েছে।

attestKey পদ্ধতিটি সত্যায়িত কী-তে একটি সর্বজনীন কী অপারেশন হিসাবে বিবেচিত হয়, কারণ এটি যে কোনও সময় কল করা যেতে পারে এবং অনুমোদনের সীমাবদ্ধতা পূরণের প্রয়োজন নেই। উদাহরণস্বরূপ, যদি সত্যায়িত কীটির ব্যবহারের জন্য ব্যবহারকারীর প্রমাণীকরণের প্রয়োজন হয়, তবে ব্যবহারকারীর প্রমাণীকরণ ছাড়াই একটি প্রমাণীকরণ তৈরি করা যেতে পারে।

প্রত্যয়ন সনদ

প্রত্যয়ন শংসাপত্র হল একটি প্রমিত X.509 শংসাপত্র, একটি ঐচ্ছিক প্রত্যয়ন এক্সটেনশন সহ যা প্রত্যয়িত কীটির একটি বিবরণ ধারণ করে। শংসাপত্রটি একটি প্রত্যয়িত সত্যায়ন কী দিয়ে স্বাক্ষরিত। প্রত্যয়ন কী প্রত্যয়িত কী থেকে আলাদা অ্যালগরিদম ব্যবহার করতে পারে।

প্রত্যয়ন শংসাপত্রে নীচের সারণীতে ক্ষেত্র রয়েছে এবং এতে কোনো অতিরিক্ত ক্ষেত্র থাকতে পারে না। কিছু ক্ষেত্র একটি নির্দিষ্ট ক্ষেত্রের মান নির্দিষ্ট করে। CTS পরীক্ষাগুলি যাচাই করে যে শংসাপত্রের বিষয়বস্তু ঠিক যেমন সংজ্ঞায়িত করা হয়েছে।

সার্টিফিকেট ক্রম

ক্ষেত্রের নাম ( RFC 5280 দেখুন) মান
tbs সার্টিফিকেট টিবিএসসি সার্টিফিকেট সিকোয়েন্স
স্বাক্ষর অ্যালগরিদম অ্যালগরিদমের অ্যালগরিদম আইডেন্টিফায়ার কী সাইন ইন করতে ব্যবহৃত হয়:
EC কীগুলির জন্য ECDSA, RSA কীগুলির জন্য RSA৷
স্বাক্ষর মান BIT STRING, ASN.1 DER-এনকোডেড tbs সার্টিফিকেটের স্বাক্ষর গণনা করা হয়েছে।

টিবিএসসি সার্টিফিকেট সিকোয়েন্স

ক্ষেত্রের নাম ( RFC 5280 দেখুন) মান
version পূর্ণসংখ্যা 2 (মানে v3 শংসাপত্র)
serialNumber পূর্ণসংখ্যা 1 (নির্দিষ্ট মান: সমস্ত শংসাপত্রে একই)
signature অ্যালগরিদমের অ্যালগরিদম আইডেন্টিফায়ার কী সাইন ইন করতে ব্যবহৃত হয়: EC কীগুলির জন্য ECDSA, RSA কীগুলির জন্য RSA৷
issuer ব্যাচের প্রত্যয়ন কী-এর বিষয় ক্ষেত্রের মতোই।
validity Tag::ACTIVE_DATETIME এবং Tag::USAGE_EXPIRE_DATETIME এর মান সমন্বিত দুটি তারিখের SEQUENCE। এই মানগুলি 1 জানুয়ারী, 1970 থেকে মিলিসেকেন্ডে রয়েছে৷ সার্টিফিকেটগুলিতে সঠিক তারিখ উপস্থাপনের জন্য RFC 5280 দেখুন৷
যদি Tag::ACTIVE_DATETIME উপস্থিত না থাকে, Tag::CREATION_DATETIME এর মান ব্যবহার করুন। Tag::USAGE_EXPIRE_DATETIME উপস্থিত না থাকলে, ব্যাচের প্রত্যয়ন কী শংসাপত্রের মেয়াদ শেষ হওয়ার তারিখ ব্যবহার করুন।
subject CN = "অ্যান্ড্রয়েড কীস্টোর কী" (নির্দিষ্ট মান: সমস্ত শংসাপত্রে একই)
subjectPublicKeyInfo SubjectPublicKeyInfo সত্যায়িত সর্বজনীন কী ধারণকারী।
extensions/Key Usage digitalSignature: সেট করুন যদি কীটির উদ্দেশ্য থাকে KeyPurpose::SIGN বা KeyPurpose::VERIFY । অন্য সব বিট সেট করা নেই।
extensions/CRL Distribution Points মান TBD
extensions/"attestation" OID হল 1.3.6.1.4.1.11129.2.1.17; বিষয়বস্তু নীচের প্রত্যয়ন এক্সটেনশন বিভাগে সংজ্ঞায়িত করা হয়েছে। সমস্ত X.509 শংসাপত্রের এক্সটেনশনগুলির মতো, বিষয়বস্তুটি একটি OCTET_STRING হিসাবে উপস্থাপন করা হয়েছে যাতে প্রত্যয়ন SEQUENCE এর একটি DER এনকোডিং রয়েছে৷

প্রত্যয়ন এক্সটেনশন

attestation এক্সটেনশনে কী-এর সাথে যুক্ত কী-মাস্টার অনুমোদনের সম্পূর্ণ বিবরণ রয়েছে, এমন একটি কাঠামোতে যা সরাসরি Android এবং কীমাস্টার HAL-এ ব্যবহৃত অনুমোদনের তালিকার সাথে মিলে যায়। একটি অনুমোদন তালিকার প্রতিটি ট্যাগ একটি ASN.1 SEQUENCE এন্ট্রি দ্বারা উপস্থাপিত হয়, স্পষ্টভাবে কীমাস্টার ট্যাগ নম্বরের সাথে ট্যাগ করা হয়, কিন্তু টাইপ বর্ণনাকারী (চারটি উচ্চ ক্রম বিট) মুখোশযুক্ত।

উদাহরণস্বরূপ, Keymaster 3-এ Tag::PURPOSE কে type.hal এ ENUM_REP | 1 প্রত্যয়ন এক্সটেনশনের জন্য, ট্যাগ 1 রেখে ENUM_REP মানটি সরানো হয়েছে। (কীমাস্টার 2 এবং নীচের জন্য, KM_TAG_PURPOSE keymaster_defs.h-এ সংজ্ঞায়িত করা হয়েছে)

এই সারণী অনুসারে মানগুলিকে ASN.1 প্রকারে সহজবোধ্যভাবে অনুবাদ করা হয়েছে:

কীমাস্টার টাইপ ASN.1 প্রকার
ENUM পূর্ণসংখ্যা
ENUM_REP পূর্ণসংখ্যার সেট
UINT পূর্ণসংখ্যা
UINT_REP পূর্ণসংখ্যার সেট
ULONG পূর্ণসংখ্যা
ULONG_REP পূর্ণসংখ্যার সেট
DATE পূর্ণসংখ্যা (1 জানুয়ারী, 1970 00:00:00 GMT থেকে মিলিসেকেন্ড)
BOOL NULL (কীমাস্টারে, বর্তমান ট্যাগ মানে সত্য, অনুপস্থিত মানে মিথ্যা।
একই শব্দার্থ ASN.1 এনকোডিংয়ের ক্ষেত্রে প্রযোজ্য)
BIGNUM বর্তমানে ব্যবহৃত হয় না, তাই কোন ম্যাপিং সংজ্ঞায়িত করা হয় না
BYTES OCTET_STRING

স্কিমা

প্রত্যয়ন এক্সটেনশন বিষয়বস্তু নিম্নলিখিত ASN.1 স্কিমা দ্বারা বর্ণনা করা হয়.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

কী বর্ণনা ক্ষেত্র

keymasterVersion এবং attestationChallenge ক্ষেত্রগুলি ট্যাগের পরিবর্তে অবস্থানগতভাবে চিহ্নিত করা হয়, তাই এনকোড করা ফর্মের ট্যাগগুলি শুধুমাত্র ক্ষেত্রের ধরন নির্দিষ্ট করে৷ অবশিষ্ট ক্ষেত্রগুলি স্কিমাতে নির্দিষ্ট করা হিসাবে অন্তর্নিহিতভাবে ট্যাগ করা হয়েছে।

ক্ষেত্র নাম টাইপ মান
attestationVersion পূর্ণসংখ্যা প্রত্যয়ন স্কিমার সংস্করণ: 1, 2, বা 3।
attestationSecurity নিরাপত্তার মাত্রা এই প্রত্যয়নের নিরাপত্তা স্তর। হার্ডওয়্যার-ব্যাকড কীগুলির সফ্টওয়্যার প্রত্যয়ন পাওয়া সম্ভব। অ্যান্ড্রয়েড সিস্টেমের সাথে আপোস করা হলে এই ধরনের প্রত্যয়ন বিশ্বাস করা যায় না।
keymasterVersion পূর্ণসংখ্যা কীমাস্টার ডিভাইসের সংস্করণ: 0, 1, 2, 3, বা 4।
keymasterSecurity নিরাপত্তার মাত্রা কীমাস্টার বাস্তবায়নের নিরাপত্তা স্তর।
attestationChallenge OCTET_STRING Tag::ATTESTATION_CHALLENGE , প্রত্যয়ন অনুরোধে নির্দিষ্ট করা হয়েছে।
uniqueId OCTET_STRING ঐচ্ছিক অনন্য ID, কী Tag::INCLUDE_UNIQUE_ID থাকলে উপস্থিত
softwareEnforced অনুমোদন তালিকা ঐচ্ছিক, কীমাস্টার অনুমোদন যা TEE দ্বারা প্রয়োগ করা হয় না, যদি থাকে।
teeEnforced অনুমোদন তালিকা ঐচ্ছিক, কীমাস্টার অনুমোদন যা TEE দ্বারা প্রয়োগ করা হয়, যদি থাকে।

অনুমোদন তালিকা ক্ষেত্র

AuthorizationList ক্ষেত্রগুলি সমস্ত ঐচ্ছিক এবং কীমাস্টার ট্যাগ মান দ্বারা চিহ্নিত করা হয়, টাইপ বিটগুলি মাস্ক করা হয়। স্পষ্ট ট্যাগিং ব্যবহার করা হয় তাই ক্ষেত্রগুলিতে একটি ট্যাগও থাকে যা তাদের ASN.1 প্রকার নির্দেশ করে, সহজ পার্সিংয়ের জন্য।

প্রতিটি ক্ষেত্রের মান সম্পর্কে বিস্তারিত জানার জন্য, Keymaster 3 এর জন্য types.hal এবং Keymaster 2 এবং নীচের জন্য keymaster_defs.h দেখুন। Keymaster ট্যাগের নামগুলি KM_TAG উপসর্গ বাদ দিয়ে এবং অবশিষ্টটিকে উটের ক্ষেত্রে পরিবর্তন করে ক্ষেত্রের নামে রূপান্তরিত হয়েছিল, তাই Tag::KEY_SIZE হয়ে ওঠে keySize

RootOfTrust ক্ষেত্র

RootOfTrust ক্ষেত্রগুলি অবস্থানগতভাবে চিহ্নিত করা হয়।

ক্ষেত্র নাম টাইপ মান
verifiedBootKey OCTET_STRING সিস্টেম ইমেজ যাচাই করতে ব্যবহৃত কীটির একটি সুরক্ষিত হ্যাশ। SHA-256 প্রস্তাবিত।
deviceLocked বুলিয়ান বুটলোডার লক করা থাকলে সত্য, যার মানে শুধুমাত্র স্বাক্ষরিত ছবি ফ্ল্যাশ করা যেতে পারে, এবং যাচাইকৃত বুট চেকিং সম্পন্ন হয়।
verifiedBootState যাচাইকৃত বুটস্টেট যাচাইকৃত বুটের অবস্থা।
verifiedBootHash OCTET_STRING যাচাইকৃত বুট দ্বারা সুরক্ষিত সমস্ত ডেটার একটি ডাইজেস্ট। যে ডিভাইসগুলি ভেরিফাইড বুটের অ্যান্ড্রয়েড ভেরিফাইড বুট ইমপ্লিমেন্টেশন ব্যবহার করে, এই মানটিতে VBMeta স্ট্রাকচার বা যাচাইকৃত বুট মেটাডেটা স্ট্রাকচারের ডাইজেস্ট রয়েছে। এই মানটি কীভাবে গণনা করা যায় সে সম্পর্কে আরও জানতে, ভিবিমেটা ডাইজেস্ট দেখুন

যাচাইকৃত বুটস্টেট মান

verifiedBootState এর মানগুলির নিম্নলিখিত অর্থ রয়েছে:

মান অর্থ
Verified বুটলোডার, বুট পার্টিশন, এবং সমস্ত যাচাইকৃত পার্টিশন সহ বুটলোডার থেকে যাচাইকৃত পার্টিশনে প্রসারিত বিশ্বাসের একটি সম্পূর্ণ চেইন নির্দেশ করে।
এই অবস্থায়, verifiedBootKey মান হল এমবেডেড সার্টিফিকেটের হ্যাশ, যার অর্থ অপরিবর্তনীয় শংসাপত্র ROM-এ বার্ন করা হয়েছে।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থা সবুজ বুট অবস্থার সাথে মিলে যায়।
SelfSigned নির্দেশ করে যে বুট পার্টিশনটি এমবেডেড সার্টিফিকেট ব্যবহার করে যাচাই করা হয়েছে, এবং স্বাক্ষরটি বৈধ। বুটলোডার বুট প্রক্রিয়া চালিয়ে যাওয়ার অনুমতি দেওয়ার আগে একটি সতর্কতা এবং সর্বজনীন কী-এর আঙুলের ছাপ প্রদর্শন করে।
এই অবস্থায়, verifiedBootKey মান হল স্ব-স্বাক্ষরকারী শংসাপত্রের হ্যাশ।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থা হলুদ বুট অবস্থার সাথে মিলে যায়।
Unverified একটি ডিভাইস অবাধে পরিবর্তিত হতে পারে নির্দেশ করে। আউট-অফ-ব্যান্ড যাচাই করার জন্য ডিভাইসের অখণ্ডতা ব্যবহারকারীর উপর ছেড়ে দেওয়া হয়। বুটলোডার বুট প্রক্রিয়া চালিয়ে যাওয়ার অনুমতি দেওয়ার আগে ব্যবহারকারীকে একটি সতর্কতা প্রদর্শন করে।
এই অবস্থায় verifiedBootKey মান খালি।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থাটি কমলা বুট অবস্থার সাথে মিলে যায়।
Failed ডিভাইসটি যাচাই করতে ব্যর্থ হয়েছে তা নির্দেশ করে। কোনো প্রত্যয়ন শংসাপত্র আসলে এই মানটি ধারণ করে না, কারণ এই অবস্থায় বুটলোডার বন্ধ হয়ে যায়। এটি সম্পূর্ণতার জন্য এখানে অন্তর্ভুক্ত করা হয়েছে।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থা লাল বুট অবস্থার সাথে মিলে যায়।

নিরাপত্তা স্তরের মান

securityLevel এর মানগুলির নিম্নলিখিত অর্থ রয়েছে:

মান অর্থ
Software যে কোডটি প্রাসঙ্গিক উপাদান (প্রত্যয়ন বা কী) তৈরি করে বা পরিচালনা করে তা অ্যান্ড্রয়েড সিস্টেমে প্রয়োগ করা হয় এবং সেই সিস্টেমে আপস করা হলে তা পরিবর্তন করা যেতে পারে।
TrustedEnvironment যে কোডটি প্রাসঙ্গিক উপাদান (প্রত্যয়ন বা কী) তৈরি বা পরিচালনা করে তা একটি বিশ্বস্ত এক্সিকিউশন এনভায়রনমেন্টে (TEE) প্রয়োগ করা হয়। যদি TEE এর সাথে আপোস করা হয় তবে এটি পরিবর্তন করা যেতে পারে, কিন্তু TEE দূরবর্তী সমঝোতার জন্য অত্যন্ত প্রতিরোধী এবং সরাসরি হার্ডওয়্যার আক্রমণ দ্বারা আপস করার জন্য মাঝারিভাবে প্রতিরোধী।
StrongBox যে কোডটি প্রাসঙ্গিক উপাদান (প্রত্যয়ন বা কী) তৈরি করে বা পরিচালনা করে তা একটি ডেডিকেটেড হার্ডওয়্যার নিরাপত্তা মডিউলে প্রয়োগ করা হয়। হার্ডওয়্যার নিরাপত্তা মডিউল আপস করা হলে এটি পরিবর্তন করা যেতে পারে, তবে এটি দূরবর্তী সমঝোতার জন্য অত্যন্ত প্রতিরোধী এবং সরাসরি হার্ডওয়্যার আক্রমণ দ্বারা আপস করার জন্য অত্যন্ত প্রতিরোধী।

অনন্য আইডি

ইউনিক আইডি হল একটি 128-বিট মান যা ডিভাইসটিকে শনাক্ত করে, কিন্তু শুধুমাত্র সীমিত সময়ের জন্য। মান এর সাথে গণনা করা হয়:

HMAC_SHA256(T || C || R, HBK)

কোথায়:

  • T হল "টেম্পোরাল কাউন্টার ভ্যালু", Tag::CREATION_DATETIME এর মানকে 2592000000 দ্বারা ভাগ করে, যে কোনো অবশিষ্টাংশ ফেলে দিয়ে গণনা করা হয়। T প্রতি 30 দিনে পরিবর্তিত হয় (2592000000 = 30 * 24 * 60 * 60 * 1000)।
  • C হল Tag::APPLICATION_ID এর মান
  • R হল 1 যদি Tag::RESET_SINCE_ID_ROTATION attest_key কলের attest_params প্যারামিটারে উপস্থিত থাকে, অথবা ট্যাগটি উপস্থিত না থাকলে 0 হয়।
  • HBK একটি অনন্য হার্ডওয়্যার-বাউন্ড সিক্রেট যা বিশ্বস্ত এক্সিকিউশন এনভায়রনমেন্টের কাছে পরিচিত এবং এটি কখনই প্রকাশ করে না। গোপনটিতে কমপক্ষে 128 বিট এনট্রপি রয়েছে এবং এটি পৃথক ডিভাইসের জন্য অনন্য (128 বিট এনট্রপি দেওয়া হলে সম্ভাব্য স্বতন্ত্রতা গ্রহণযোগ্য)। HBK HMAC বা AES_CMAC এর মাধ্যমে ফিউজড কী উপাদান থেকে প্রাপ্ত হওয়া উচিত।

HMAC_SHA256 আউটপুটকে 128 বিটে ছোট করুন।

প্রত্যয়ন কী এবং সার্টিফিকেট

দুটি কী, একটি RSA এবং একটি ECDSA, এবং সংশ্লিষ্ট শংসাপত্র চেইনগুলি, সুরক্ষিতভাবে ডিভাইসে সরবরাহ করা হয়েছে৷

অ্যান্ড্রয়েড 12 রিমোট কী প্রভিশনিং প্রবর্তন করে, এবং অ্যান্ড্রয়েড 13-এর জন্য ডিভাইসগুলি এটি প্রয়োগ করা প্রয়োজন। রিমোট কী প্রভিশনিং প্রতি-অ্যাপ্লিকেশন, ECDSA P256 প্রত্যয়ন শংসাপত্র সহ ক্ষেত্রে ডিভাইস সরবরাহ করে। এই শংসাপত্রগুলি কারখানার প্রভিশনেড সার্টিফিকেটের তুলনায় স্বল্প মেয়াদী।

আইডি প্রত্যয়ন

Android 8.0-এ কীমাস্টার 3-এর সাথে ডিভাইসগুলির জন্য আইডি প্রত্যয়নের জন্য ঐচ্ছিক সমর্থন অন্তর্ভুক্ত রয়েছে। আইডি প্রত্যয়ন ডিভাইসটিকে তার হার্ডওয়্যার শনাক্তকারীর প্রমাণ প্রদান করতে দেয়, যেমন সিরিয়াল নম্বর বা IMEI। যদিও একটি ঐচ্ছিক বৈশিষ্ট্য, এটি অত্যন্ত বাঞ্ছনীয় যে সমস্ত Keymaster 3 বাস্তবায়ন এটির জন্য সমর্থন প্রদান করে কারণ ডিভাইসের পরিচয় প্রমাণ করতে সক্ষম হওয়ার ফলে ট্রু জিরো-টাচ রিমোট কনফিগারেশনের মতো ব্যবহারের ক্ষেত্রে আরও নিরাপদ হতে সক্ষম হয় (কারণ দূরবর্তী দিকটি নিশ্চিত হতে পারে সঠিক ডিভাইসের সাথে কথা বলছে, কোনো ডিভাইস তার পরিচয় ফাঁকি দিচ্ছে না)।

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

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

স্টোরেজ বৈশিষ্ট্য

ডিভাইসের শনাক্তকারী ধারণ করা স্টোরেজে এই বৈশিষ্ট্য থাকা প্রয়োজন:

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

নির্মাণ

উপরে তালিকাভুক্ত বৈশিষ্ট্য রয়েছে এমন একটি বাস্তবায়ন তৈরি করতে, নিম্নলিখিত নির্মাণ S-এ ID-প্রাপ্ত মানগুলি সংরক্ষণ করুন। সিস্টেমের স্বাভাবিক স্থানগুলি ব্যতীত ID-এর মানগুলির অন্যান্য অনুলিপি সংরক্ষণ করবেন না, যা কোনও ডিভাইস মালিক রুট করার মাধ্যমে সংশোধন করতে পারে:

S = D || HMAC(HBK, D)

কোথায়:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC হল একটি উপযুক্ত সুরক্ষিত হ্যাশ সহ HMAC নির্মাণ (SHA-256 প্রস্তাবিত)
  • HBK একটি হার্ডওয়্যার-বাউন্ড কী অন্য কোনো উদ্দেশ্যে ব্যবহার করা হয় না
  • ID 1 ...ID n হল আসল ID মান; একটি নির্দিষ্ট সূচকের সাথে একটি নির্দিষ্ট মানের সংযুক্তি বাস্তবায়ন-নির্ভর, কারণ বিভিন্ন ডিভাইসে বিভিন্ন সংখ্যক শনাক্তকারী থাকবে
  • || সংমিশ্রণ প্রতিনিধিত্ব করে

যেহেতু HMAC আউটপুটগুলি নির্দিষ্ট আকারের, তাই পৃথক আইডি হ্যাশ বা D-এর HMAC খুঁজে পাওয়ার জন্য কোনো শিরোনাম বা অন্য কাঠামোর প্রয়োজন নেই। প্রত্যয়ন সম্পাদনের জন্য প্রদত্ত মানগুলি পরীক্ষা করার পাশাপাশি, বাস্তবায়নগুলিকে S থেকে D বের করে S যাচাই করতে হবে , HMAC(HBK, D) কম্পিউটিং করে এবং এটিকে S-এর মানের সাথে তুলনা করে যাচাই করে যে কোনো পৃথক আইডি পরিবর্তন/দুর্নীতি করা হয়নি। এছাড়াও, বাস্তবায়নে অবশ্যই সমস্ত স্বতন্ত্র ID উপাদানগুলির জন্য ধ্রুব-সময়ের তুলনা ব্যবহার করতে হবে এবং S-এর বৈধতা অবশ্যই প্রদত্ত আইডির সংখ্যা এবং পরীক্ষার যেকোনো অংশের সঠিক মিল নির্বিশেষে স্থির হতে হবে।

হার্ডওয়্যার শনাক্তকারী

আইডি প্রত্যয়ন নিম্নলিখিত হার্ডওয়্যার সনাক্তকারী সমর্থন করে:

  1. ব্র্যান্ডের নাম, যেমনটি Android-এ Build.BRAND দ্বারা ফেরত দেওয়া হয়েছে
  2. Android-এ Build.DEVICE দ্বারা ফেরত দেওয়া ডিভাইসের নাম
  3. Android-এ Build.PRODUCT দ্বারা ফেরত দেওয়া পণ্যের নাম
  4. নির্মাতার নাম, যেমনটি Android-এ Build.MANUFACTURER দ্বারা ফেরত দেওয়া হয়েছে
  5. মডেলের নাম, যেমনটি Android-এ Build.MODEL দ্বারা ফেরত দেওয়া হয়েছে৷
  6. ক্রমিক সংখ্যা
  7. সমস্ত রেডিওর IMEI
  8. সমস্ত রেডিওর MEID

ডিভাইস আইডি প্রত্যয়ন সমর্থন করার জন্য, একটি ডিভাইস এই শনাক্তকারীদের প্রমাণ করে। অ্যান্ড্রয়েড চালিত সমস্ত ডিভাইসে প্রথম ছয়টি রয়েছে এবং এই বৈশিষ্ট্যটি কাজ করার জন্য সেগুলি প্রয়োজনীয়। ডিভাইসটিতে কোনো সমন্বিত সেলুলার রেডিও থাকলে, ডিভাইসটিকে অবশ্যই IMEI এবং/অথবা রেডিওগুলির MEID-এর জন্য প্রত্যয়ন সমর্থন করতে হবে।

একটি মূল প্রত্যয়ন সম্পাদন করে এবং অনুরোধে সত্যায়িত করার জন্য ডিভাইস শনাক্তকারী সহ আইডি প্রত্যয়ন অনুরোধ করা হয়। শনাক্তকারীকে ট্যাগ করা হয়েছে:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

প্রত্যয়িত শনাক্তকারী একটি UTF-8 এনকোড করা বাইট স্ট্রিং। এই বিন্যাসটি সংখ্যাসূচক শনাক্তকারীর ক্ষেত্রেও প্রযোজ্য। প্রত্যয়িত প্রতিটি শনাক্তকারী একটি UTF-8 এনকোডেড স্ট্রিং হিসাবে প্রকাশ করা হয়।

যদি ডিভাইসটি আইডি প্রত্যয়নকে সমর্থন না করে (অথবা destroyAttestationIds() আগে কল করা হয়েছিল এবং ডিভাইসটি আর তার আইডিগুলিকে সত্যায়িত করতে পারে না), তাহলে এই ট্যাগগুলির একটি বা একাধিক অন্তর্ভুক্ত যেকোন মূল প্রত্যয়ন অনুরোধ ErrorCode::CANNOT_ATTEST_IDS এর সাথে ব্যর্থ হয়।

যদি ডিভাইসটি আইডি প্রত্যয়ন সমর্থন করে এবং উপরের এক বা একাধিক ট্যাগ একটি মূল প্রত্যয়ন অনুরোধে অন্তর্ভুক্ত করা হয়, TEE যাচাই করে যে প্রতিটি ট্যাগের সাথে সরবরাহ করা শনাক্তকারী তার হার্ডওয়্যার শনাক্তকারীর অনুলিপির সাথে মেলে। যদি এক বা একাধিক শনাক্তকারী মেলে না, ErrorCode::CANNOT_ATTEST_IDS এর সাথে সম্পূর্ণ প্রত্যয়ন ব্যর্থ হয়। একই ট্যাগ একাধিকবার সরবরাহ করার জন্য এটি বৈধ। এটি উপযোগী হতে পারে, উদাহরণস্বরূপ, IMEI গুলি প্রত্যয়িত করার সময়: একটি ডিভাইসে একাধিক IMEI সহ একাধিক রেডিও থাকতে পারে৷ যদি প্রতিটি ATTESTATION_ID_IMEI এর সাথে সরবরাহ করা মানটি ডিভাইসের একটি রেডিওর সাথে মেলে তবে একটি সত্যায়ন অনুরোধ বৈধ৷ একই অন্য সব ট্যাগ প্রযোজ্য.

প্রত্যয়ন সফল হলে, উপরে থেকে স্কিমা ব্যবহার করে জারি করা প্রত্যয়নপত্রের প্রত্যয়ন এক্সটেনশনে (OID 1.3.6.1.4.1.11129.2.1.17) সত্যায়িত আইডি যোগ করা হয়। Keymaster 2 প্রত্যয়ন স্কিমা থেকে পরিবর্তনগুলি মন্তব্য সহ বোল্ড করা হয়েছে৷

জাভা API

এই বিভাগটি শুধুমাত্র তথ্যমূলক। কীমাস্টার বাস্তবায়নকারীরা জাভা API প্রয়োগ বা ব্যবহার করে না। এটি প্রয়োগকারীদের বুঝতে সাহায্য করার জন্য প্রদান করা হয়েছে যে কীভাবে বৈশিষ্ট্যটি অ্যাপ্লিকেশনগুলি ব্যবহার করে। সিস্টেমের উপাদানগুলি এটিকে ভিন্নভাবে ব্যবহার করতে পারে, এই কারণেই এটি গুরুত্বপূর্ণ যে এই বিভাগটিকে আদর্শ হিসাবে বিবেচনা করা হবে না।

,

কীস্টোর একটি নিয়ন্ত্রিত উপায়ে ক্রিপ্টোগ্রাফিক কী তৈরি, সঞ্চয় এবং ব্যবহার করার জন্য আরও নিরাপদ স্থান প্রদান করে। যখন হার্ডওয়্যার-ব্যাকড কী স্টোরেজ পাওয়া যায় এবং ব্যবহার করা হয়, তখন মূল উপাদান ডিভাইস থেকে নিষ্কাশনের বিরুদ্ধে আরও নিরাপদ, এবং কীমাস্টার এমন বিধিনিষেধ প্রয়োগ করে যেগুলি বিকৃত করা কঠিন।

এটি শুধুমাত্র সত্য, তবে, যদি কী-স্টোর কীগুলি হার্ডওয়্যার-ব্যাকড স্টোরেজে বলে জানা যায়। Keymaster 1-এ, অ্যাপস বা রিমোট সার্ভারের জন্য এই ঘটনাটি ছিল কিনা তা নির্ভরযোগ্যভাবে যাচাই করার কোনো উপায় ছিল না। কীস্টোর ডেমন উপলব্ধ কীমাস্টার HAL লোড করেছে এবং কীগুলির হার্ডওয়্যার ব্যাকিংয়ের ক্ষেত্রে HAL যা বলেছে তা বিশ্বাস করে।

এর প্রতিকারের জন্য, Keymaster Android 7.0 (Keymaster 2) একী প্রত্যয়ন এবং Android 8.0 (Keymaster 3) এ আইডি প্রত্যয়ন চালু করেছে।

কী প্রত্যয়নের লক্ষ্য হল একটি অপ্রতিসম কী জোড়া হার্ডওয়্যার-সমর্থিত কিনা, কীটির বৈশিষ্ট্যগুলি কী এবং এর ব্যবহারে কোন সীমাবদ্ধতাগুলি প্রয়োগ করা হয়েছে তা দৃঢ়ভাবে নির্ধারণ করার একটি উপায় প্রদান করা।

আইডি প্রত্যয়ন ডিভাইসটিকে তার হার্ডওয়্যার শনাক্তকারীর প্রমাণ প্রদান করতে দেয়, যেমন সিরিয়াল নম্বর বা IMEI।

মূল প্রত্যয়ন

মূল প্রত্যয়ন সমর্থন করার জন্য, Android 7.1 HAL-তে ট্যাগ, টাইপ এবং পদ্ধতির একটি সেট প্রবর্তন করেছে।

ট্যাগ

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

টাইপ

কীমাস্টার 2 এবং নীচে

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

AttestKey পদ্ধতি

কীমাস্টার 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

কীমাস্টার 2 এবং নীচে

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev হল কীমাস্টার ডিভাইস স্ট্রাকচার।
  • keyToAttest হল generateKey থেকে ফিরে আসা কী ব্লব যার জন্য প্রত্যয়ন তৈরি করা হবে।
  • attestParams হল প্রত্যয়নের জন্য প্রয়োজনীয় যে কোনো পরামিতির একটি তালিকা। এর মধ্যে রয়েছে Tag::ATTESTATION_CHALLENGE এবং সম্ভবত Tag::RESET_SINCE_ID_ROTATION , সেইসাথে Tag::APPLICATION_ID এবং Tag::APPLICATION_DATA । পরবর্তী দুটি কী ব্লব ডিক্রিপ্ট করার জন্য প্রয়োজনীয় যদি সেগুলি কী তৈরির সময় নির্দিষ্ট করা হয়।
  • certChain হল আউটপুট প্যারামিটার, যা শংসাপত্রের একটি অ্যারে প্রদান করে। এন্ট্রি 0 হল প্রত্যয়ন শংসাপত্র, যার অর্থ এটি keyToAttest থেকে কীটি প্রত্যয়িত করে এবং এতে প্রত্যয়ন এক্সটেনশন রয়েছে।

attestKey পদ্ধতিটি সত্যায়িত কী-তে একটি সর্বজনীন কী অপারেশন হিসাবে বিবেচিত হয়, কারণ এটি যে কোনও সময় কল করা যেতে পারে এবং অনুমোদনের সীমাবদ্ধতা পূরণের প্রয়োজন নেই। উদাহরণস্বরূপ, যদি সত্যায়িত কীটির ব্যবহারের জন্য ব্যবহারকারীর প্রমাণীকরণের প্রয়োজন হয়, তবে ব্যবহারকারীর প্রমাণীকরণ ছাড়াই একটি প্রমাণীকরণ তৈরি করা যেতে পারে।

প্রত্যয়ন সনদ

প্রত্যয়ন শংসাপত্র হল একটি প্রমিত X.509 শংসাপত্র, একটি ঐচ্ছিক প্রত্যয়ন এক্সটেনশন সহ যা প্রত্যয়িত কীটির একটি বিবরণ ধারণ করে। শংসাপত্রটি একটি প্রত্যয়িত সত্যায়ন কী দিয়ে স্বাক্ষরিত। প্রত্যয়ন কী প্রত্যয়িত কী থেকে আলাদা অ্যালগরিদম ব্যবহার করতে পারে।

প্রত্যয়ন শংসাপত্রে নীচের সারণীতে ক্ষেত্র রয়েছে এবং এতে কোনো অতিরিক্ত ক্ষেত্র থাকতে পারে না। কিছু ক্ষেত্র একটি নির্দিষ্ট ক্ষেত্রের মান নির্দিষ্ট করে। CTS পরীক্ষাগুলি যাচাই করে যে শংসাপত্রের বিষয়বস্তু ঠিক যেমন সংজ্ঞায়িত করা হয়েছে।

সার্টিফিকেট ক্রম

ক্ষেত্রের নাম ( RFC 5280 দেখুন) মান
tbs সার্টিফিকেট টিবিএসসি সার্টিফিকেট সিকোয়েন্স
স্বাক্ষর অ্যালগরিদম অ্যালগরিদমের অ্যালগরিদম আইডেন্টিফায়ার কী সাইন ইন করতে ব্যবহৃত হয়:
EC কীগুলির জন্য ECDSA, RSA কীগুলির জন্য RSA৷
স্বাক্ষর মান BIT STRING, ASN.1 DER-এনকোডেড tbs সার্টিফিকেটের স্বাক্ষর গণনা করা হয়েছে।

টিবিএসসি সার্টিফিকেট সিকোয়েন্স

ক্ষেত্রের নাম ( RFC 5280 দেখুন) মান
version পূর্ণসংখ্যা 2 (মানে v3 শংসাপত্র)
serialNumber পূর্ণসংখ্যা 1 (নির্দিষ্ট মান: সমস্ত শংসাপত্রে একই)
signature অ্যালগরিদমের অ্যালগরিদম আইডেন্টিফায়ার কী সাইন ইন করতে ব্যবহৃত হয়: EC কীগুলির জন্য ECDSA, RSA কীগুলির জন্য RSA৷
issuer ব্যাচের প্রত্যয়ন কী-এর বিষয় ক্ষেত্রের মতোই।
validity Tag::ACTIVE_DATETIME এবং Tag::USAGE_EXPIRE_DATETIME এর মান সমন্বিত দুটি তারিখের SEQUENCE। এই মানগুলি 1 জানুয়ারী, 1970 থেকে মিলিসেকেন্ডে রয়েছে৷ সার্টিফিকেটগুলিতে সঠিক তারিখ উপস্থাপনের জন্য RFC 5280 দেখুন৷
যদি Tag::ACTIVE_DATETIME উপস্থিত না থাকে, Tag::CREATION_DATETIME এর মান ব্যবহার করুন। Tag::USAGE_EXPIRE_DATETIME উপস্থিত না থাকলে, ব্যাচের প্রত্যয়ন কী শংসাপত্রের মেয়াদ শেষ হওয়ার তারিখ ব্যবহার করুন।
subject CN = "অ্যান্ড্রয়েড কীস্টোর কী" (নির্দিষ্ট মান: সমস্ত শংসাপত্রে একই)
subjectPublicKeyInfo SubjectPublicKeyInfo সত্যায়িত সর্বজনীন কী ধারণকারী।
extensions/Key Usage digitalSignature: সেট করুন যদি কীটির উদ্দেশ্য থাকে KeyPurpose::SIGN বা KeyPurpose::VERIFY । অন্য সব বিট সেট করা নেই।
extensions/CRL Distribution Points মান TBD
extensions/"attestation" OID হল 1.3.6.1.4.1.11129.2.1.17; বিষয়বস্তু নীচের প্রত্যয়ন এক্সটেনশন বিভাগে সংজ্ঞায়িত করা হয়েছে। সমস্ত X.509 শংসাপত্রের এক্সটেনশনগুলির মতো, বিষয়বস্তুটি একটি OCTET_STRING হিসাবে উপস্থাপন করা হয়েছে যাতে প্রত্যয়ন SEQUENCE এর একটি DER এনকোডিং রয়েছে৷

প্রত্যয়ন এক্সটেনশন

attestation এক্সটেনশনে কী-এর সাথে যুক্ত কী-মাস্টার অনুমোদনের সম্পূর্ণ বিবরণ রয়েছে, এমন একটি কাঠামোতে যা সরাসরি Android এবং কীমাস্টার HAL-এ ব্যবহৃত অনুমোদনের তালিকার সাথে মিলে যায়। একটি অনুমোদন তালিকার প্রতিটি ট্যাগ একটি ASN.1 SEQUENCE এন্ট্রি দ্বারা উপস্থাপিত হয়, স্পষ্টভাবে কীমাস্টার ট্যাগ নম্বরের সাথে ট্যাগ করা হয়, কিন্তু টাইপ বর্ণনাকারী (চারটি উচ্চ ক্রম বিট) মুখোশযুক্ত।

উদাহরণস্বরূপ, Keymaster 3-এ Tag::PURPOSE কে type.hal এ ENUM_REP | 1 প্রত্যয়ন এক্সটেনশনের জন্য, ট্যাগ 1 রেখে ENUM_REP মানটি সরানো হয়েছে। (কীমাস্টার 2 এবং নীচের জন্য, KM_TAG_PURPOSE keymaster_defs.h-এ সংজ্ঞায়িত করা হয়েছে)

এই সারণী অনুসারে মানগুলিকে ASN.1 প্রকারে সহজবোধ্যভাবে অনুবাদ করা হয়েছে:

কীমাস্টার টাইপ ASN.1 প্রকার
ENUM পূর্ণসংখ্যা
ENUM_REP পূর্ণসংখ্যার সেট
UINT পূর্ণসংখ্যা
UINT_REP পূর্ণসংখ্যার সেট
ULONG পূর্ণসংখ্যা
ULONG_REP পূর্ণসংখ্যার সেট
DATE পূর্ণসংখ্যা (1 জানুয়ারী, 1970 00:00:00 GMT থেকে মিলিসেকেন্ড)
BOOL NULL (কীমাস্টারে, বর্তমান ট্যাগ মানে সত্য, অনুপস্থিত মানে মিথ্যা।
একই শব্দার্থ ASN.1 এনকোডিংয়ের ক্ষেত্রে প্রযোজ্য)
BIGNUM বর্তমানে ব্যবহৃত হয় না, তাই কোন ম্যাপিং সংজ্ঞায়িত করা হয় না
BYTES OCTET_STRING

স্কিমা

প্রত্যয়ন এক্সটেনশন বিষয়বস্তু নিম্নলিখিত ASN.1 স্কিমা দ্বারা বর্ণনা করা হয়.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

কী বর্ণনা ক্ষেত্র

keymasterVersion এবং attestationChallenge ক্ষেত্রগুলি ট্যাগের পরিবর্তে অবস্থানগতভাবে চিহ্নিত করা হয়, তাই এনকোড করা ফর্মের ট্যাগগুলি শুধুমাত্র ক্ষেত্রের ধরন নির্দিষ্ট করে৷ অবশিষ্ট ক্ষেত্রগুলি স্কিমাতে নির্দিষ্ট করা হিসাবে অন্তর্নিহিতভাবে ট্যাগ করা হয়েছে।

ক্ষেত্র নাম টাইপ মান
attestationVersion পূর্ণসংখ্যা প্রত্যয়ন স্কিমার সংস্করণ: 1, 2, বা 3।
attestationSecurity নিরাপত্তার মাত্রা এই প্রত্যয়নের নিরাপত্তা স্তর। হার্ডওয়্যার-ব্যাকড কীগুলির সফ্টওয়্যার প্রত্যয়ন পাওয়া সম্ভব। অ্যান্ড্রয়েড সিস্টেমের সাথে আপোস করা হলে এই ধরনের প্রত্যয়ন বিশ্বাস করা যায় না।
keymasterVersion পূর্ণসংখ্যা কীমাস্টার ডিভাইসের সংস্করণ: 0, 1, 2, 3, বা 4।
keymasterSecurity নিরাপত্তার মাত্রা কীমাস্টার বাস্তবায়নের নিরাপত্তা স্তর।
attestationChallenge OCTET_STRING Tag::ATTESTATION_CHALLENGE , প্রত্যয়ন অনুরোধে নির্দিষ্ট করা হয়েছে।
uniqueId OCTET_STRING ঐচ্ছিক অনন্য ID, কী Tag::INCLUDE_UNIQUE_ID থাকলে উপস্থিত
softwareEnforced অনুমোদন তালিকা ঐচ্ছিক, কীমাস্টার অনুমোদন যা TEE দ্বারা প্রয়োগ করা হয় না, যদি থাকে।
teeEnforced অনুমোদন তালিকা ঐচ্ছিক, কীমাস্টার অনুমোদন যা TEE দ্বারা প্রয়োগ করা হয়, যদি থাকে।

অনুমোদন তালিকা ক্ষেত্র

AuthorizationList ক্ষেত্রগুলি সমস্ত ঐচ্ছিক এবং কীমাস্টার ট্যাগ মান দ্বারা চিহ্নিত করা হয়, টাইপ বিটগুলি মাস্ক করা হয়। স্পষ্ট ট্যাগিং ব্যবহার করা হয় তাই ক্ষেত্রগুলিতে একটি ট্যাগও থাকে যা তাদের ASN.1 প্রকার নির্দেশ করে, সহজ পার্সিংয়ের জন্য।

প্রতিটি ক্ষেত্রের মান সম্পর্কে বিস্তারিত জানার জন্য, Keymaster 3 এর জন্য types.hal এবং Keymaster 2 এবং নীচের জন্য keymaster_defs.h দেখুন। Keymaster ট্যাগের নামগুলি KM_TAG উপসর্গ বাদ দিয়ে এবং অবশিষ্টটিকে উটের ক্ষেত্রে পরিবর্তন করে ক্ষেত্রের নামে রূপান্তরিত হয়েছিল, তাই Tag::KEY_SIZE হয়ে ওঠে keySize

RootOfTrust ক্ষেত্র

RootOfTrust ক্ষেত্রগুলি অবস্থানগতভাবে চিহ্নিত করা হয়।

ক্ষেত্র নাম টাইপ মান
verifiedBootKey OCTET_STRING সিস্টেম ইমেজ যাচাই করতে ব্যবহৃত কীটির একটি সুরক্ষিত হ্যাশ। SHA-256 প্রস্তাবিত।
deviceLocked বুলিয়ান বুটলোডার লক করা থাকলে সত্য, যার মানে শুধুমাত্র স্বাক্ষরিত ছবি ফ্ল্যাশ করা যেতে পারে, এবং যাচাইকৃত বুট চেকিং সম্পন্ন হয়।
verifiedBootState যাচাইকৃত বুটস্টেট যাচাইকৃত বুটের অবস্থা।
verifiedBootHash OCTET_STRING যাচাইকৃত বুট দ্বারা সুরক্ষিত সমস্ত ডেটার একটি ডাইজেস্ট। যে ডিভাইসগুলি ভেরিফাইড বুটের অ্যান্ড্রয়েড ভেরিফাইড বুট ইমপ্লিমেন্টেশন ব্যবহার করে, এই মানটিতে VBMeta স্ট্রাকচার বা যাচাইকৃত বুট মেটাডেটা স্ট্রাকচারের ডাইজেস্ট রয়েছে। এই মানটি কীভাবে গণনা করা যায় সে সম্পর্কে আরও জানতে, ভিবিমেটা ডাইজেস্ট দেখুন

যাচাইকৃত বুটস্টেট মান

verifiedBootState এর মানগুলির নিম্নলিখিত অর্থ রয়েছে:

মান অর্থ
Verified বুটলোডার, বুট পার্টিশন, এবং সমস্ত যাচাইকৃত পার্টিশন সহ বুটলোডার থেকে যাচাইকৃত পার্টিশনে প্রসারিত বিশ্বাসের একটি সম্পূর্ণ চেইন নির্দেশ করে।
এই অবস্থায়, verifiedBootKey মান হল এমবেডেড সার্টিফিকেটের হ্যাশ, যার অর্থ অপরিবর্তনীয় শংসাপত্র ROM-এ বার্ন করা হয়েছে।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থা সবুজ বুট অবস্থার সাথে মিলে যায়।
SelfSigned নির্দেশ করে যে বুট পার্টিশনটি এমবেডেড সার্টিফিকেট ব্যবহার করে যাচাই করা হয়েছে, এবং স্বাক্ষরটি বৈধ। বুটলোডার বুট প্রক্রিয়া চালিয়ে যাওয়ার অনুমতি দেওয়ার আগে একটি সতর্কতা এবং সর্বজনীন কী-এর আঙুলের ছাপ প্রদর্শন করে।
এই অবস্থায়, verifiedBootKey মান হল স্ব-স্বাক্ষরকারী শংসাপত্রের হ্যাশ।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থা হলুদ বুট অবস্থার সাথে মিলে যায়।
Unverified একটি ডিভাইস অবাধে পরিবর্তিত হতে পারে নির্দেশ করে। আউট-অফ-ব্যান্ড যাচাই করার জন্য ডিভাইসের অখণ্ডতা ব্যবহারকারীর উপর ছেড়ে দেওয়া হয়। বুটলোডার বুট প্রক্রিয়া চালিয়ে যাওয়ার অনুমতি দেওয়ার আগে ব্যবহারকারীকে একটি সতর্কতা প্রদর্শন করে।
এই অবস্থায় verifiedBootKey মান খালি।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থাটি কমলা বুট অবস্থার সাথে মিলে যায়।
Failed ডিভাইসটি যাচাই করতে ব্যর্থ হয়েছে তা নির্দেশ করে। কোনো প্রত্যয়ন শংসাপত্র আসলে এই মানটি ধারণ করে না, কারণ এই অবস্থায় বুটলোডার বন্ধ হয়ে যায়। এটি সম্পূর্ণতার জন্য এখানে অন্তর্ভুক্ত করা হয়েছে।
যাচাইকৃত বুট ফ্লো ডকুমেন্টেশনে নথিভুক্ত হিসাবে এই অবস্থা লাল বুট অবস্থার সাথে মিলে যায়।

নিরাপত্তা স্তরের মান

securityLevel এর মানগুলির নিম্নলিখিত অর্থ রয়েছে:

মান অর্থ
Software যে কোডটি প্রাসঙ্গিক উপাদান (প্রত্যয়ন বা কী) তৈরি করে বা পরিচালনা করে তা অ্যান্ড্রয়েড সিস্টেমে প্রয়োগ করা হয় এবং সেই সিস্টেমে আপস করা হলে তা পরিবর্তন করা যেতে পারে।
TrustedEnvironment যে কোডটি প্রাসঙ্গিক উপাদান (প্রত্যয়ন বা কী) তৈরি বা পরিচালনা করে তা একটি বিশ্বস্ত এক্সিকিউশন এনভায়রনমেন্টে (TEE) প্রয়োগ করা হয়। যদি TEE এর সাথে আপোস করা হয় তবে এটি পরিবর্তন করা যেতে পারে, কিন্তু TEE দূরবর্তী সমঝোতার জন্য অত্যন্ত প্রতিরোধী এবং সরাসরি হার্ডওয়্যার আক্রমণ দ্বারা আপস করার জন্য মাঝারিভাবে প্রতিরোধী।
StrongBox যে কোডটি প্রাসঙ্গিক উপাদান (প্রত্যয়ন বা কী) তৈরি করে বা পরিচালনা করে তা একটি ডেডিকেটেড হার্ডওয়্যার নিরাপত্তা মডিউলে প্রয়োগ করা হয়। হার্ডওয়্যার নিরাপত্তা মডিউল আপস করা হলে এটি পরিবর্তন করা যেতে পারে, তবে এটি দূরবর্তী সমঝোতার জন্য অত্যন্ত প্রতিরোধী এবং সরাসরি হার্ডওয়্যার আক্রমণ দ্বারা আপস করার জন্য অত্যন্ত প্রতিরোধী।

Unique ID

The Unique ID is a 128-bit value that identifies the device, but only for a limited period of time. The value is computed with:

HMAC_SHA256(T || C || R, HBK)

Where:

  • T is the "temporal counter value", computed by dividing the value of Tag::CREATION_DATETIME by 2592000000, dropping any remainder. T changes every 30 days (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C is the value of Tag::APPLICATION_ID
  • R is 1 if Tag::RESET_SINCE_ID_ROTATION is present in the attest_params parameter to the attest_key call, or 0 if the tag is not present.
  • HBK is a unique hardware-bound secret known to the Trusted Execution Environment and never revealed by it. The secret contains at least 128 bits of entropy and is unique to the individual device (probabilistic uniqueness is acceptable given the 128 bits of entropy). HBK should be derived from fused key material via HMAC or AES_CMAC.

Truncate the HMAC_SHA256 output to 128 bits.

Attestation keys and certificates

Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are securely provisioned into the device.

Android 12 introduces Remote Key Provisioning, and Android 13 requires devices implement it. Remote Key Provisioning provides devices in the field with per-application, ECDSA P256 attestation certificates. These certificates are shorter-lived than the factory-provisioned certificates.

ID attestation

Android 8.0 includes optional support for ID attestation for devices with Keymaster 3. ID attestation allows the device to provide proof of its hardware identifiers, such as serial number or IMEI. Although an optional feature, it is highly recommended that all Keymaster 3 implementations provide support for it because being able to prove the device's identity enables use cases such as true zero-touch remote configuration to be more secure (because the remote side can be certain it is talking to the right device, not a device spoofing its identity).

ID attestation works by creating copies of the device's hardware identifiers that only the Trusted Execution Environment (TEE) can access before the device leaves the factory. A user may unlock the device's bootloader and change the system software and the identifiers reported by the Android frameworks. The copies of the identifiers held by the TEE cannot be manipulated in this way, ensuring that device ID attestation will only ever attest to the device's original hardware identifiers thereby thwarting spoofing attempts.

The main API surface for ID attestation builds on top of the existing key attestation mechanism introduced with Keymaster 2. When requesting an attestation certificate for a key held by keymaster, the caller may request that the device's hardware identifiers be included in the attestation certificate's metadata. If the key is held in the TEE, the certificate will chain back to a known root of trust. The recipient of such a certificate can verify that the certificate and its contents, including the hardware identifiers, were written by the TEE. When asked to include hardware identifiers in the attestation certificate, the TEE attests only to the identifiers held in its storage, as populated on the factory floor.

Storage properties

The storage that holds the device's identifiers needs to have these properties:

  • The values derived from the device's original identifiers are copied to the storage before the device leaves the factory.
  • The destroyAttestationIds() method can permanently destroy this copy of the identifier-derived data. Permanent destruction means the data is completely removed so neither a factory reset nor any other procedure performed on the device can restore it. This is especially important for devices where a user has unlocked the bootloader and changed the system software and modified the identifiers returned by Android frameworks.
  • RMA facilities should have the ability to generate fresh copies of the hardware identifier-derived data. This way, a device that passes through RMA can perform ID attestation again. The mechanism used by RMA facilities must be protected so that users cannot invoke it themselves, as that would allow them to obtain attestations of spoofed IDs.
  • No code other than Keymaster trusted app in the TEE is able to read the identifier-derived data kept in the storage.
  • The storage is tamper-evident: If the content of the storage has been modified, the TEE treats it the same as if the copies of the content had been destroyed and refuses all ID attestation attempts. This is implemented by signing or MACing the storage as described below .
  • The storage does not hold the original identifiers. Because ID attestation involves a challenge, the caller always supplies the identifiers to be attested. The TEE only needs to verify that these match the values they originally had. Storing secure hashes of the original values rather than the values enables this verification.

Construction

To create an implementation that has the properties listed above, store the ID-derived values in the following construction S. Do not store other copies of the ID values, excepting the normal places in the system, which a device owner may modify by rooting:

S = D || HMAC(HBK, D)

where:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC is the HMAC construction with an appropriate secure hash (SHA-256 recommended)
  • HBK is a hardware-bound key not used for any other purpose
  • ID 1 ...ID n are the original ID values; association of a particular value to a particular index is implementation-dependent, as different devices will have different numbers of identifiers
  • || represents concatenation

Because the HMAC outputs are fixed size, no headers or other structure are required to be able to find individual ID hashes, or the HMAC of D. In addition to checking provided values to perform attestation, implementations need to validate S by extracting D from S, computing HMAC(HBK, D) and comparing it to the value in S to verify that no individual IDs were modified/corrupted. Also, implementations must use constant-time comparisons for all individual ID elements and the validation of S. Comparison time must be constant regardless of the number of IDs provided and the correct matching of any part of the test.

Hardware identifiers

ID attestation supports the following hardware identifiers:

  1. Brand name, as returned by Build.BRAND in Android
  2. Device name, as returned by Build.DEVICE in Android
  3. Product name, as returned by Build.PRODUCT in Android
  4. Manufacturer name, as returned by Build.MANUFACTURER in Android
  5. Model name, as returned by Build.MODEL in Android
  6. Serial number
  7. IMEIs of all radios
  8. MEIDs of all radios

To support device ID attestation, a device attests to these identifiers. All devices running Android have the first six and they are necessary for this feature to work. If the device has any integrated cellular radios, the device must also support attestation for the IMEIs and/or MEIDs of the radios.

ID attestation is requested by performing a key attestation and including the device identifiers to attest in the request. The identifiers are tagged as:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

The identifier to attest is a UTF-8 encoded byte string. This format applies to numerical identifiers, as well. Each identifier to attest is expressed as a UTF-8 encoded string.

If the device does not support ID attestation (or destroyAttestationIds() was previously called and the device can no longer attest its IDs), any key attestation request that includes one or more of these tags fails with ErrorCode::CANNOT_ATTEST_IDS .

If the device supports ID attestation and one or more of the above tags have been included in a key attestation request, the TEE verifies the identifier supplied with each of the tags matches its copy of the hardware identifiers. If one or more identifiers do not match, the entire attestation fails with ErrorCode::CANNOT_ATTEST_IDS . It is valid for the same tag to be supplied multiple times. This can be useful, for example, when attesting IMEIs: A device may have multiple radios with multiple IMEIs. An attestation request is valid if the value supplied with each ATTESTATION_ID_IMEI matches one of the device's radios. The same applies to all other tags.

If attestation is successful, the attested IDs is added to the attestation extension (OID 1.3.6.1.4.1.11129.2.1.17) of the issued attestation certificate, using the schema from above . Changes from the Keymaster 2 attestation schema are bolded , with comments.

Java API

This section is informational only. Keymaster implementers neither implement nor use the Java API. This is provided to help implementers understand how the feature is used by applications. System components may use it differently, which is why it's crucial this section not be treated as normative.