שיטת האימות

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

איך מאמתים את גיבוי הקושחה של Pixel

דרישות מוקדמות לאימות

לפני שמאמתים שהרכיב (קושחה או APK) תואם לטענה, צריך לוודא שהכלים הבאים זמינים במחשב שמחובר לרשת. בהתאם ליעד האימות, יכול להיות שלא תצטרכו את כולם.

Golang

כלי האימות כתוב ב-Go. כדי לבנות אותו, צריך להתקין את Go 1.24 ואילך מהאתר של Go.

‫Android Debug Bridge‏ (ADB)

‫ADB הוא כלי שמתקשר עם מכשיר Android כדי לבדוק את התמונה או לחלץ קובצי APK. הכלי זמין באתר של Android SDK Platform Tools‏ .

כלי לאימות הוכחת הכללה

המאמת של הוכחת ההכללה הוא מודול Go ששולח שאילתות ליומן השקיפות, ומפיק פלט שמציין אם פריט המידע כלול ביומן. הוא מתפרסם במאגר של android-binary-transparency ב-GitHub בכתובת https://github.com/android/android-binary-transparency/tree/main

כדי לשכפל את המאגר של AOSP avb:

computer:~$ git clone https://android.googlesource.com/platform/external/avb

כדי לשכפל את מאגר android-binary-transparency GitHub:

computer:~$ git clone https://github.com/android/android-binary-transparency

AAPT2

‫AAPT2 (Android Asset Packaging Tool) הוא כלי לבנייה שמשמש לקומפילציה ולאריזה של משאבים של אפליקציית Android. הכלי הזה זמין ככלי עצמאי ב-Android SDK Build Tools מגרסה 26.0.2 ואילך.

כלי Bundletool

‫bundletool הוא כלי שמשמש ליצירת קובץ Android App Bundle ‏ (AAB). אפשר להשתמש בו גם כדי לאמת חתימות קוד של APK. אפשר להוריד אותו מ-GitHub.

‫wget או curl

‫wget ו-curl הם כלים שאפשר להשתמש בהם כדי לאחזר או להוריד קבצים מהאינטרנט. חשוב לוודא שאחד מהכלים האלה מותקן, כי יכול להיות שתסריטי האימות יסתמכו עליהם.

Avbtool

avbtool משמש לחישוב תקציר ה-VBMeta של קובצי האימג' להגדרות המקוריות ולאימות של קבצים בינאריים. אחרי שמשכפלים את המאגר של avb (כפי שמוצג בקטע "אימות הוכחת הכללה"), אפשר למצוא את avbtool.py בתוך הספרייה המשוכפלת של avb. צריך להוסיף את הספרייה הזו למשתנה הסביבה $PATH.

computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL

Fbpacktool

‫fbpacktool הוא סקריפט Python שמשמש לחילוץ רכיבים בודדים ב-bootloader.img של Pixel. אין צורך בכך אם מאמתים קובצי APK. הכלי הזה חשוב כי הוא מאפשר ל-avbtool.py לגלות את התמונות הנדרשות לאימות.

‫fbpacktool דורש Python בגרסה 3.6 ואילך, ואת חבילת PyYAML (לדוגמה, python3 -m pip install pyyaml).

כדי להשתמש בכלי הזה, צריך להוריד את ששת סקריפטי Python הבאים לספרייה שבה נמצא הקובץ avbtool.py, להגדיר את fbpacktool.py כקובץ הפעלה וליצור קישור סמלי בשם fbpacktool אל fbpacktool.py לנוחות השימוש.

אם יש לכם wget:

computer:dir_to_avbtool$ wget https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpacktool.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpack.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/packedstruct.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlparser.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlserializer.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/yamlparser.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

אם יש לכם curl:

computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpacktool.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpack.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/packedstruct.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlparser.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlserializer.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/yamlparser.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

OpenSSL

‫openssl עוזר לבצע פעולות קריפטוגרפיות שונות באמצעות הטרמינל בתהליך העבודה של האימות. מוודאים שהיא מותקנת במערכת. כדי לבדוק בטרמינל, מריצים את הפקודה הבאה ומוודאים שהתוצאה שמוחזרת לא ריקה:

computer:~$ which openssl
/usr/bin/openssl

יצירת מטען ייעודי (payload) לאימות

כדי לאמת את קובץ האימג' במכשיר או קובץ שהורדתם מאתר Pixel Factory Image, קודם צריך ליצור את המטען הייעודי (payload) שתואם לקובץ האימג' הזה מהמאפיינים הייחודיים של גרסת ה-build ומהתקציר של VBMeta. יש שתי אפשרויות, ידנית או אוטומטית, כפי שמתואר בהמשך.

  • מאפיינים ייחודיים של גרסת build: מזהה מחרוזת של גיבוי קושחה
    • לדוגמה: google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
  • VBMeta Digest: גיבוב קריפטוגרפי מסוג SHA-256 שמקשר בין החלקים השונים של תמונות המפעל
    • לדוגמה: 4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe

יצירה ידנית של מטען ייעודי (payload)

כדי ליצור באופן ידני את המטען הייעודי (payload) לאימות, צריך ליצור קובץ טקסט, payload.txt, שמכיל את המאפיינים הייחודיים של גרסת ה-build בשורה אחת ואת תקציר ה-VBMeta בשורה הבאה, עם שורה חדשה ריקה (אפשר לעיין בקטע "תוכן היומן" כדי לראות את הפורמט המדויק).

אחרי שמבצעים את השלבים שמופיעים באתר של גיבוי קושחה, התוכן של הקובץ payload.txt אמור להיראות כך:

google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe
חילוץ סיכום VBMeta ומאפיינים ייחודיים של גרסת build מאתר גיבוי הקושחה של Pixel

כשמורידים תמונת מערכת מהאתר תמונות המערכת של Pixel, צריך לפתוח את הקובץ שהורד, וכך תיצור תיקייה נוספת במקום. עוברים לתיקייה החדשה שנוצרה ומחלצים את קובץ ה-image-*.zip המשויך כדי לקבל קובצי *.img נפרדים. הקבצים הבינאריים האלה הם תמונות של מחיצות. מוודאים שקובץ vbmeta.img קיים בין קובצי ה-img. אמורה להופיע הודעה כזו:

computer:oriole-sd1a.210817.015.a4$ unzip image-oriole-sd1a.210817.015.a4.zip
Archive:  image-oriole-sd1a.210817.015.a4.zip
  inflating: android-info.txt
  inflating: boot.img
  inflating: vendor_boot.img
  inflating: system.img
  inflating: vendor.img
  inflating: product.img
  inflating: system_ext.img
  inflating: system_other.img
  inflating: dtbo.img
  inflating: vbmeta_system.img
  inflating: vbmeta.img
  inflating: super_empty.img

אתם יכולים לחלץ את המאפיינים הייחודיים של גרסת ה-build ולחשב את תקציר ה-VBMeta מכל הקבצים שהורדתם.

אחרי ש-avbtool.py יהיה זמין ב-$PATH, תוכלו להריץ את הפקודות הבאות מהטרמינל כדי לחלץ את מאפיינים ייחודיים של גרסת build הספציפית למכשיר ולחשב את הגיבוב של VBMeta של גיבוי הקושחה שזה עתה הורדתם:

computer:dir_containing_unzipped_factory_image~$ grep -a 'ro\.product\.build\.fingerprint=google/.*/release-keys' product.img | cut -f2 -d'='
google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
computer:dir_containing_unzipped_factory_image$ avbtool.py calculate_vbmeta_digest --image vbmeta.img
4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe
אימות ידני של גיבוי קושחה שהורד

כדי לאמת בצורה נכונה את קובץ ה-factory image שהורדתם, תצטרכו להוריד את fbpacktool.py ואת קובצי ה-Python האחרים שהוא תלוי בהם (הרשימה המלאה ופקודות ההורדה מפורטות בקטע Fbpacktool בדרישות המוקדמות) כדי לפרוק את הרכיבים ב-bootloader.img, כפי שהם מתוארים בנפרד במבנה VBMeta. אחרי שמקבלים את הכלי לפריקת קבצים, אפשר להשתמש ב-fbpacktool.py כדי לפרוק את תמונת תוכנת האתחול. לדוגמה:

computer:dir_containing_unzipped_images$ python3 fbpacktool.py unpack bootloader-oriole-slider-1.0-7683913.img

אמורים להופיע קובצי ‎ .img נוספים בספרייה הזו. עכשיו אפשר להמשיך להשתמש ב-avbtool.py כדי לוודא באופן ידני שהחתימות של המחיצות השונות תואמות.

computer:dir_containing_unzipped_images$ avbtool.py verify_image --image vbmeta.img --follow_chain_partitions
Verifying image vbmeta.img using embedded public key
vbmeta: Successfully verified SHA256_RSA4096 vbmeta struct in vbmeta.img
vbmeta_system: Chained but ROLLBACK_SLOT (which is 1) and KEY (which has sha1 df529646b7225015196a714006346f0768b87fcf) not specified
--
Verifying image vbmeta_system.img using embedded public key
vbmeta: Successfully verified SHA256_RSA4096 vbmeta struct in vbmeta_system.img
product: Successfully verified sha256 hashtree of product.img for image of 2700468224 bytes
system: Successfully verified sha256 hashtree of system.img for image of 878493696 bytes
system_ext: Successfully verified sha256 hashtree of system_ext.img for image of 251334656 bytes
vbmeta_vendor: Chained but ROLLBACK_SLOT (which is 3) and KEY (which has sha1 85322346680a860c091fa14a64cef1fe4a3ffe31) not specified
--
Verifying image vbmeta_vendor.img using embedded public key
vbmeta: Successfully verified SHA256_RSA4096 vbmeta struct in vbmeta_vendor.img
vendor: Successfully verified sha256 hashtree of vendor.img for image of 472940544 bytes
boot: Chained but ROLLBACK_SLOT (which is 2) and KEY (which has sha1 85322346680a860c091fa14a64cef1fe4a3ffe31) not specified
--
Verifying image boot.img using embedded public key
vbmeta: Successfully verified footer and SHA256_RSA4096 vbmeta struct in boot.img
boot: Successfully verified sha256 hash of boot.img for image of 24481792 bytes
abl: Successfully verified sha256 hash of abl.img for image of 1744896 bytes
bl1: Successfully verified sha256 hash of bl1.img for image of 12288 bytes
bl2: Successfully verified sha256 hash of bl2.img for image of 544768 bytes
bl31: Successfully verified sha256 hash of bl31.img for image of 86016 bytes
dtbo: Successfully verified sha256 hash of dtbo.img for image of 2152234 bytes
gsa: Successfully verified sha256 hash of gsa.img for image of 262144 bytes
ldfw: Successfully verified sha256 hash of ldfw.img for image of 4096000 bytes
pbl: Successfully verified sha256 hash of pbl.img for image of 49152 bytes
tzsw: Successfully verified sha256 hash of tzsw.img for image of 4304896 bytes
vendor_boot: Successfully verified sha256 hash of vendor_boot.img for image of 25718784 bytes
vendor_dlkm: Successfully verified sha256 hashtree of vendor_dlkm.img for image of 54505472 bytes

אם לא מופיעות הודעות שגיאה או הודעות על כשל, סימן שה-VBMeta של קובץ האימג' שהורדתם אומת בהצלחה.

בניית מטען ייעודי (payload) אוטומטית

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

computer:dir_to_avb_repo/tools/transparency$ python3 ./pixel_factory_image_verify.py https://dl.google.com/dl/android/aosp/oriole-sd1a.210817.015.a4-factory-074b7f51.zip
Fetching file from: https://dl.google.com/dl/android/aosp/oriole-sd1a.210817.015.a4-factory-074b7f51.zip
Successfully downloaded file.
Successfully unpacked factory image.
Successfully unpacked factory image partitions.
Successfully unpacked bootloader image.
Successfully verified VBmeta.
Successfully extracted build fingerprint.
Successfully calculated VBMeta Digest.
The build fingerprint for factory image is: google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
The VBMeta Digest for factory image is: 4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe

A corresponding "payload.txt" file has been created.

הפעלת הפקודה שלמעלה תוריד את חבילת קובצי ה-ROM, תפתח את החבילה ותאמת את החתימות של המחיצות החתומות. אחרי האימות, ייווצר קובץ חדש בשם payload.txt, והתוכן שלו אמור להיראות בערך כך:

google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe

אחרי שיוצרים את הקובץ payload.txt, אפשר להתחיל את השלבים של אימות הכללת התמונה.

אימות הכללת התמונה (הוכחת הכללה)

אחרי שיוצרים את מטען הייעודי (payload), מגדירים משתנה של מעטפת (למשל, $PAYLOAD_PATH) שיצביע על הנתיב למטען הייעודי.

כלי להוכחת הכללה פורסם במאגר avb במסגרת פרויקט הקוד הפתוח של Android. כדי להפעיל את הפתרונות:

computer:external/avb/tools/transparency/verify$ PAYLOAD_PATH=../payload.txt
computer:external/avb/tools/transparency/verify$ go build cmd/verifier/verifier.go
computer:external/avb/tools/transparency/verify$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=pixel

המאמת משתמש בנקודת הבדיקה ובתוכן היומן (שנמצא בספריית המשבצות) כדי לוודא שמטען הייעודי (payload) של קובץ האימג' נמצא ביומן השקיפות, כלומר שהוא פורסם על ידי Google.

הפלט של הפקודה נכתב ב-stdout:

  • ‫OK. inclusion check success! אם התמונה נכללת ביומן,
  • FAILURE אם לא.