קישור גרסה

ב-Keymaster 1, כל מפתחות ה-Keymaster קושרו באופן קריפטוגרפי למכשיר Root of Trust או מפתח ההפעלה המאומתת. ב-Keymaster 2 ו-3, הכול מפתחות קשורים גם לרמת מערכת ההפעלה ולרמת התיקון של תמונת המערכת. כך ניתן להבטיח שתוקפים שמגלה נקודות חולשה גרסה של תוכנת המערכת או תוכנת TEE לא יכולה להחזיר מכשיר למצב פגיע ולהשתמש במפתחות שנוצרו עם הגרסה החדשה יותר. בנוסף, כאשר מפתח עם גרסה מסוימת ורמת תיקון מסוימת נמצאים בשימוש במכשיר ששודרג לגרסה חדשה יותר או לרמת תיקון חדשה יותר, המפתח ישודרג לפני שניתן יהיה להשתמש בו, והגרסה הקודמת של המפתח בוטלה. בשיטה הזאת, מכיוון שהמכשיר ישודרגו, המקשים יעברו "ראצ'ט" קדימה עם המכשיר, אבל כל הפיכת המכשיר לגרסה קודמת תגרום לכך שהמפתחות שלא ניתן לשימוש.

כדי לתמוך במבנה המודולרי של טרבל ולבטל את הקישור של system.img אל start.img, Keymaster 4 שינה את מודל הקישור של גרסת המפתח כך שיהיה נפרד רמות תיקון לכל מחיצה. כך אפשר לעדכן כל מחיצה באופן עצמאי, ועדיין לספק הגנה מפני החזרה.

ב-Android 9: boot, system וvendor לכל מחיצות יש רמת תיקון משלה.

  • במכשירים עם 'הפעלה מאומתת של Android' (AVB) אפשר לבצע את כל רמות התיקון ואת גרסת המערכת ב-vbmeta, כך שתוכנת האתחול יכולה לספק להם 'מנהל מפתחות'. עבור מחיצות משורשרות, פרטי הגרסה של המחיצה להיות ב-vbmeta בשרשרת. באופן כללי, פרטי הגרסה צריכים להיות vbmeta struct שמכיל את נתוני האימות (גיבוב או hashtree) למחיצה נתונה.
  • במכשירים ללא AVB:
    • הטמעות של הפעלה מאומתת צריכות לספק גיבוב של הגרסה מטא-נתונים לתוכנת האתחול, כדי שתוכנת האתחול תוכל לספק את הגיבוב ל-Keymaster.
    • boot.img יכול להמשיך לשמור את רמת התיקון בכותרת
    • system.img יכול להמשיך לאחסן את רמת התיקון ואת גרסת מערכת ההפעלה במצב קריאה בלבד נכסים
    • רמת התיקון נשמרת בנכס לקריאה בלבד על ידי vendor.img ro.vendor.build.version.security_patch.
    • תוכנת האתחול יכולה לספק גיבוב של כל הנתונים שאומתו על ידי הפעלה מאומתת ועד ל-Keymaster.
  • ב-Android 9, יש להשתמש בתגים הבאים כדי לספק פרטי גרסה עבור את המחיצות הבאות:
    • VENDOR_PATCH_LEVEL: המחיצה vendor
    • BOOT_PATCH_LEVEL: המחיצה boot
    • OS_PATCH_LEVEL וגם OS_VERSION: מחיצה system. (OS_VERSION הוסר מתוך הכותרת boot.img.
  • הטמעות Keymaster צריכות להתייחס לכל רמות התיקון בנפרד. המקשים הם אפשר להשתמש בו אם כל פרטי הגרסה תואמים לערכים שמשויכים למפתח, וגם IKeymaster::upgradeDevice() מעביר לרמת תיקון גבוהה יותר אם הדרושים.

שינויים ב-HAL

כדי לתמוך בקישור גרסאות ובאימות (attestation) גרסה, נוספו ל-Android 7.1 את תגים Tag::OS_VERSION ו-Tag::OS_PATCHLEVEL השיטות configure ו-upgradeKey. תגי הגרסאות נוספים באופן אוטומטי על ידי הטמעות Keymaster 2 ואילך לכל האפליקציות החדשות שנוצרו מפתחות (או מעודכנים). בנוסף, כל ניסיון להשתמש במפתח שאין לו מערכת הפעלה גרסה או רמת תיקון שתואמים לגרסה הנוכחית של מערכת ההפעלה או לרמת התיקון, בהתאמה, נדחה באמצעות ErrorCode::KEY_REQUIRES_UPGRADE.

Tag::OS_VERSION הוא ערך UINT שמייצג את חלקים ראשיים, משניים ותת-קלים בגרסת מערכת Android כ-MMmmss כאשר MM הוא הגרסה הראשית, mm הוא הגרסה המשנית ו-ss הוא הגרסה המשנית . לדוגמה, הערך 6.1.2 מיוצג בתור 060102.

Tag::OS_PATCHLEVEL הוא ערך UINT שמייצג את השנה והחודש של העדכון האחרון במערכת בתור YYYYMM, כאשר YYYY הוא שנה בארבע ספרות ו-MM הוא שתי הספרות של החודש. לדוגמה, מרץ 2016 יהיה שמיוצגת כ-201603.

מפתח שדרוג

כדי לאפשר שדרוג מפתחות לגרסת מערכת ההפעלה החדשה ולרמת התיקון של המערכת תמונה, מערכת Android 7.1 הוסיף את השיטה upgradeKey ל-HAL:

Keymaster 3

    upgradeKey(vec keyBlobToUpgrade, vec upgradeParams)
        generates(ErrorCode error, vec upgradedKeyBlob);

Keymaster 2

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, שדרושים לפענוח המפתח blob, אם הם סופקו במהלך היצירה.
  • upgradedKeyBlob הוא פרמטר הפלט, שמשמש להחזרת מפתח blob חדש.

אם הקריאה אל upgradeKey היא באמצעות blob מפתח שאי אפשר לנתח או אחרת לא חוקית, היא מחזירה ErrorCode::INVALID_KEY_BLOB. אם נשלחת באמצעות מפתח שרמת התיקון שלו גדולה מערך המערכת הנוכחי, הפונקציה מחזירה את הערך ErrorCode::INVALID_ARGUMENT. אם היא מופעלת באמצעות מפתח שגרסת מערכת ההפעלה שלו גדולה מערך המערכת הנוכחי, וערך המערכת היא לא אפס, והיא מחזירה ErrorCode::INVALID_ARGUMENT. גרסת מערכת הפעלה שדרוגים ממספרים שאינם אפס לאפס מותרים. במקרה של שגיאות בתקשורת עם העולם המאובטח, הוא יחזיר ערך שגיאה מתאים (למשל ErrorCode::SECURE_HW_ACCESS_DENIED, ErrorCode::SECURE_HW_BUSY). אחרת, הפונקציה מחזירה ErrorCode::OK והחזרת blob מפתח חדש ב- upgradedKeyBlob

keyBlobToUpgrade יישאר בתוקף אחרי upgradeKey טלפון, ויכול להיות שנשתמש בו שוב אם המכשיר שודרג לאחור. לחשבון בדרך כלל, מאגר המפתחות קורא ל-deleteKey blob אחד (keyBlobToUpgrade) זמן קצר אחרי השיחה אל upgradeKey. אם היה תג באתר של keyBlobToUpgrade Tag::ROLLBACK_RESISTANT, ואז upgradedKeyBlob גם הם קיימים (והם צריכים להיות עמידים בפני החזרות).

הגדרה מאובטחת

כדי להטמיע קישור גרסאות, ל-Keymaster TA נדרשת דרך לקבל באופן מאובטח את הגרסה הנוכחית של מערכת ההפעלה ואת רמת התיקון (פרטי הגרסה), וכדי לוודא המידע שהוא מקבל תואם מאוד למידע על המודעה המערכת.

כדי לתמוך בשליחה מאובטחת של פרטי הגרסה לת"א, OS_VERSION נוסף שדה לכותרת של תמונת האתחול. גרסת ה-build של קובץ האימג' להפעלה שהסקריפט מאכלס את השדה הזה באופן אוטומטי. יצרני ציוד מקורי (OEM) ומטמיעי TA (ראשי) צריכים לפעול יחד כדי לשנות את תוכנת האתחול של המכשירים כדי לחלץ את הגרסה מידע מתמונת האתחול ומעבירים אותו לטלקומוניקציה לפני בזמן אתחול המערכת. כך ניתן לוודא שתוקפים לא יוכלו להפריע להקצאה של פרטי גרסה לת"א.

צריך גם לוודא שתמונת המערכת כוללת את אותה גרסה בתור קובץ אימג' לאתחול. לשם כך, נוספה שיטת ההגדרה ל-Keymaster HAL:

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, אבל לפני קריאה לשיטות אחרות. אם בכל שיטה אחרת נקראת לפני ההגדרה, ה-TA מחזיר ErrorCode::KEYMASTER_NOT_CONFIGURED

בפעם הראשונה שמתבצעת קריאה אל configure לאחר אתחול המכשיר, צריך לוודא שפרטי הגרסה שסופקו תואמים לפרטים שסופקו על ידי תוכנת האתחול. אם פרטי הגרסה לא תואמים, הפונקציה configure מחזירה ErrorCode::INVALID_ARGUMENT שיטות אחרות לניהול מפתחות (Keymaster) ממשיכים לחזור ErrorCode::KEYMASTER_NOT_CONFIGURED. אם הפרטים תואמים, configure מחזירה ErrorCode::OK, ומנהל מפתחות אחר השיטות מתחילות לפעול כרגיל.

הקריאות הבאות אל configure מחזירות את אותו הערך שהוחזר על ידי את הקריאה הראשונה, ואל תשנו את המצב של מנהל המפתח. שימו לב שהתהליך הזה דורשת שכל עדכוני ה-OTA יעדכנו את תמונות המערכת ואת תמונות האתחול. לא ניתן לעדכן אותם בנפרד, כדי לשמור את פרטי הגרסה מסונכרנים.

כי התוכן של configure ייקרא על ידי המערכת שנועד לאמת, יש חלון הזדמנויות מצומצם לתוקפים לפגוע בתמונת המערכת ולאלץ אותו לספק פרטי גרסה תואם לתמונת האתחול, אבל היא לא הגרסה בפועל של המערכת. שילוב של אימות תמונת אתחול, אימות dm-verity של קובץ האימג' של המערכת התוכן, והעובדה ש-configure נקרא בשלב מוקדם מאוד מערכת ההפעלה הזאת אמורה להקשות על ניצול חלון ההזדמנויות הזה.