מודול הצפנה GKI עם אישור FIPS 140-3

הליבה של GKI כוללת מודול של ליבה של Linux שנקרא fips140.ko, שעומד בדרישות של FIPS 140-3 למודולים של תוכנות קריפטוגרפיות. אפשר לשלוח את המודול הזה לאישור FIPS אם המוצר שבו פועל הליבה של GKI מחייב זאת.

כדי שאפשר יהיה להשתמש בתרחישי הקריפטו, צריך לעמוד בדרישות הבאות של FIPS 140-3:

  • המודול צריך לבדוק את התקינות שלו לפני שהאלגוריתמים הקריפטוגרפיים זמינים.
  • לפני שהמודול יהיה זמין, צריך להפעיל את האלגוריתמים הקריפטוגרפיים המאושרים שלו ולאמת אותם באמצעות בדיקות עצמיות עם תשובה ידועה.

למה מודול נפרד בליבה

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

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

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

לכן, כל הקוד שעומד בדרישות של FIPS 140-3 ארוז במודול נפרד של הליבה fips140.ko, שמסתמך רק על ממשקים יציבים שנחשפו על ידי מקור הליבה של GKI שממנו הוא נוצר. המשמעות היא שאפשר להשתמש במודול במהדורות שונות של GKI מאותה דור, וצריך לעדכן אותו ולשלוח אותו מחדש לצורך אישור רק אם תוקנו בעיות בקוד שכלול במודול עצמו.

מתי כדאי להשתמש במודול

הליבה של GKI עצמה מכילה קוד שמבוסס על תוכניות הקריפטוגרפיה שגם הן נכללות בחבילה של מודול הליבה FIPS 140-3. לכן, פונקציות הקריפטוגרפיה המובנות לא מועברות מליבת GKI, אלא מועתקות למודול. כשהמודול נטען, נוהלי הקריפטו המובנים מוסרים מרישום ב-Linux CryptoAPI ומחליפים אותם אלה שמובאים על ידי המודול.

כלומר, מודול fips140.ko הוא אופציונלי לחלוטין, ומומלץ לפרוס אותו רק אם יש צורך באישור FIPS 140-3. בנוסף, המודול לא מספק יכולות נוספות, וטעינה שלו ללא צורך צפויה להשפיע רק על זמן האתחול, בלי להניב תועלת כלשהי.

איך לפרוס את המודול

אפשר לשלב את המודול ב-build של Android באמצעות השלבים הבאים:

  • מוסיפים את שם המודול אל BOARD_VENDOR_RAMDISK_KERNEL_MODULES. כתוצאה מכך, המודול יועתק ל-ramdisk של הספק.
  • מוסיפים את שם המודול אל BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. כתוצאה מכך, שם המודול מתווסף ל-modules.load ביעד. המשתנה modules.load מכיל את רשימת המודולים שנטענים על ידי init כשהמכשיר מופעל.

בדיקה עצמית של התקינות

מודול הליבה של FIPS 140-3 לוקח את הסיכום של HMAC-SHA256 של הקטעים .code ו-.rodata שלו בזמן טעינת המודול, ומשויך אותו לסיכום שנרשם במארז. הפעולה הזו מתרחשת אחרי שטוען המודול של Linux כבר ביצע את השינויים הרגילים, כמו עיבוד המיקום של ELF ותיקון חלופות לשגיאות במעבד (CPU) בקטעים האלה. כדי לוודא שאפשר לשחזר את הסיכום בצורה נכונה, אנחנו מבצעים את הפעולות הבאות:

  • המיקומים של ELF נשמרים בתוך המודול, כך שאפשר ליישם אותם ההפוכה לקלט של ה-HMAC.
  • המודול מבטל את כל תיקוני הקוד שבוצעו על ידי הליבה (kernel) של Dynamic Shadow Call Stack. באופן ספציפי, המודול מחליף את כל ההוראות שמבצעות דחיפה או הוצאה (pop) מ-shadow call stack בהוראות של Pointer Authentication Code‏ (PAC) שהיו קיימות במקור.
  • כל שאר תיקוני הקוד מושבתים במודול, כולל מפתחות סטטיים, ולכן נקודות מעקב וכן ווקים של ספקים.

הבדיקות העצמאיות עם תשובה ידועה

כל אלגוריתם מוטמע שנכלל בדרישות של FIPS 140-3 חייב לבצע בדיקה עצמית עם תשובה ידועה לפני השימוש בו. בהתאם להנחיות להטמעה של FIPS 140-3 10.3.A, וקטור בדיקה יחיד לכל אלגוריתם באמצעות כל אחד מאורכי המפתחות הנתמכים מספיק למפתחות הצפנה, כל עוד גם ההצפנה וגם פענוח נבדקים.

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

אלגוריתמים הכלולים במודול

כל האלגוריתמים שכלולים במודול FIPS 140-3 מפורטים כאן. הכלל הזה חל על ההסתעפויות של הליבה android12-5.10,‏ android13-5.10,‏ android13-5.15,‏ android14-5.15,‏ android14-6.1 ו-android15-6.6, אבל ההבדלים בין גרסאות הליבה יצוינו במקרים הרלוונטיים.

אלגוריתם הטמעות ניתן לאישור הגדרה
aes aes-generic, ‏ aes-arm64, ‏ aes-ce, ‏ ספריית AES כן הצפנת AES רגילה של בלוקים, ללא מצב פעולה: יש תמיכה בכל גדלי המפתחות (128 ביטים, 192 ביטים ו-256 ביטים). אפשר ליצור כל הטמעות (מלבד הטמעה של הספרייה) עם מצב פעולה באמצעות תבנית.
cmac(aes) cmac (template), ‏ cmac-aes-neon, ‏ cmac-aes-ce כן AES-CMAC: יש תמיכה בכל גדלי המפתחות של AES. אפשר ליצור תבנית cmac עם כל הטמעה של aes באמצעות cmac(<aes-impl>). שאר ההטמעות הן עצמאיות.
ecb(aes) ecb (תבנית), ecb-aes-neon, ecb-aes-neonbs, ecb-aes-ce כן AES-ECB: יש תמיכה בכל גדלי המפתחות של AES. אפשר ליצור תבנית ecb עם כל הטמעה של aes באמצעות ecb(<aes-impl>). יישומים אחרים הם נפרדים.
cbc(aes) cbc (תבנית), cbc-aes-neon, cbc-aes-neonbs, cbc-aes-ce כן AES-CBC: יש תמיכה בכל גדלי המפתחות של AES. אפשר להרכיב את התבנית cbc עם כל הטמעה של aes באמצעות ctr(<aes-impl>). שאר ההטמעות הן עצמאיות.
cts(cbc(aes)) cts (template), ‏ cts-cbc-aes-neon, ‏ cts-cbc-aes-ce כן AES-CBC-CTS או AES-CBC עם גניבת טקסט מוצפן: הנוהל שבו נעשה שימוש הוא CS3; שני הבלוקים האחרונים של הטקסט המוצפן מוחלפים ללא תנאי. יש תמיכה בכל גדלי המפתחות של AES. אפשר ליצור תבנית cts עם כל הטמעה של cbc באמצעות cts(<cbc(aes)-impl>).ההטמעות האחרות הן עצמאיות.
ctr(aes) ctr (תבנית), ctr-aes-neon, ctr-aes-neonbs, ctr-aes-ce כן AES-CTR: יש תמיכה בכל גדלי המפתחות של AES. אפשר ליצור תבנית ctr עם כל הטמעה של aes באמצעות ctr(<aes-impl>). יישומים אחרים הם נפרדים.
xts(aes) xts (תבנית), xts-aes-neon, xts-aes-neonbs, xts-aes-ce כן AES-XTS: בגרסה 6.1 ואילך של הליבה, יש תמיכה בכל גדלי המפתחות של AES. בגרסה 6.6 ואילך של הליבה, יש תמיכה רק ב-AES-128 וב-AES-256. אפשר ליצור תבנית xts עם כל הטמעה של ecb(aes) באמצעות xts(<ecb(aes)-impl>). שאר ההטמעות הן עצמאיות. בכל ההטמעות מופעלת בדיקת המפתחות החלשים הנדרשת על ידי FIPS. כלומר, מפתחות XTS שהמחצית הראשונה והשנייה שלהם זהות נדחים.
gcm(aes) gcm (template), ‏ gcm-aes-ce לא1 AES-GCM: יש תמיכה בכל הגדלים של מפתחות AES. יש תמיכה רק ב-IVs של 96 ביט. כמו בכל מצבי AES האחרים במודול הזה, מבצע הקריאה החוזרת אחראי לספק את מספר ה-IV. אפשר ליצור את התבנית gcm באמצעות כל הטמעות של ctr(aes) ו-ghash באמצעות gcm_base(<ctr(aes)-impl>,<ghash-impl>). שאר ההטמעות הן עצמאיות.
sha1 sha1-generic, sha1-ce כן פונקציית גיבוב קריפטוגרפית SHA-1
sha224 sha224-generic, sha224-arm64 sha224-ce כן פונקציית גיבוב קריפטוגרפית מסוג SHA-224: הקוד משותף ל-SHA-256.
sha256 sha256-generic, ‏ sha256-arm64, ‏ sha256-ce, ‏ ספריית SHA-256 כן פונקציית גיבוב קריפטוגרפי SHA-256: ממשק ספרייה מסופק ל-SHA-256 בנוסף לממשק CryptoAPI הסטנדרטי. בממשק הספרייה הזו נעשה שימוש בהטמעה אחרת.
sha384 sha384-generic, sha384-arm64 sha384-ce כן פונקציית גיבוב (hash) קריפטוגרפית מסוג SHA-384: הקוד משותף עם האלגוריתם SHA-512.
sha512 sha512-generic, sha512-arm64 sha512-ce כן פונקציית גיבוב (hash) קריפטוגרפית מסוג SHA-512
sha3-224 sha3-224-generic כן פונקציית גיבוב (hash) קריפטוגרפית מסוג SHA3-224. האפשרות הזו קיימת רק בליבה בגרסה 6.6 ואילך.
sha3-256 sha3-256-generic כן זהה לקודם, אבל עם אורך תקציר של 256 ביט (SHA3-256). בכל אורכי הדיגסטים נעשה שימוש באותה הטמעה של Keccak.
sha3-384 sha3-384-generic כן זהה לקודם, אבל עם אורך סיכום של 384 ביט (SHA3-384). כל אורכי התקציר משתמשים באותה הטמעה של Keccak.
sha3-512 sha3-512-generic כן זהה לקודם, אבל עם אורך סיכום של 512 ביט (SHA3-512). כל אורכי התקציר משתמשים באותה הטמעה של Keccak.
hmac hmac (תבנית) כן HMAC (קוד אימות הודעות המבוסס על גיבוב מפתחות): אפשר ליצור את התבנית hmac באמצעות כל אלגוריתם SHA או הטמעה של SHA באמצעות hmac(<sha-alg>) או hmac(<sha-impl>).
stdrng drbg_pr_hmac_sha1, drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512 כן מופע של HMAC_DRBG עם פונקציית גיבוב בעלת שם והפעלת התנגדות לחיזוי: בדיקות תקינות כלולות. משתמשים בממשק הזה מקבלים מכונות DRBG משלהם.
stdrng drbg_nopr_hmac_sha1, drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512 כן זהים לאלגוריתמים של drbg_pr_*, אבל עם השבתת התכונה 'התנגדות לחיזוי'. הקוד משותף עם הווריאנט העמיד בפני חיזוי. בגרסה 5.10 של הליבה, ה-DRBG בעל העדיפות הגבוהה ביותר הוא drbg_nopr_hmac_sha256. בגרסה 5.15 ואילך של הליבה, הערך הוא drbg_pr_hmac_sha512.
jitterentropy_rng jitterentropy_rng לא Jitter RNG, גרסה 2.2.0 (גרסת ליבה 6.1 ומטה) או גרסה 3.4.0 (גרסת ליבה 6.6 ומעלה). משתמשים בממשק הזה מקבלים מכונות Jitter RNG משלהם. הם לא עושים שימוש חוזר במכונות שבהן נעשה שימוש ב-DRBG.
xcbc(aes) xcbc-aes-neon, xcbc-aes-ce לא
xctr(aes) xctr-aes-neon, xctr-aes-ce לא האפשרות קיימת רק בליבה בגרסה 5.15 ואילך.
cbcmac(aes) cbcmac-aes-neon, cbcmac-aes-ce לא
essiv(cbc(aes),sha256) essiv-cbc-aes-sha256-neon, essiv-cbc-aes-sha256-ce לא

פיתוח המודול מקוד המקור

ב-Android מגרסה 14 ואילך (כולל android-mainline), צריך ליצור את המודול fips140.ko מהמקור באמצעות הפקודות הבאות.

  • פיתוח גרסאות build באמצעות Bazel:

    tools/bazel run //common:fips140_dist
  • פיתוח גרסה זמינה להתקנה (build) עם build.sh (דור קודם):

    BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh

הפקודות האלה מבצעות build מלא, כולל הליבה והמודול fips140.ko עם תוכן הדיגסט של HMAC-SHA256 שמוטמע בו.

הנחיות למשתמשי קצה

הנחיות לקצין קריפטו

כדי להפעיל את מודול הליבה, מערכת ההפעלה צריכה להיות מוגבלת למצב הפעלה של מפעיל יחיד. מערכת Android מטפלת בזה באופן אוטומטי באמצעות חומרת ניהול זיכרון שנמצאת במעבד.

לא ניתן להתקין את מודול הליבה בנפרד. הוא נכלל כחלק מתוכנת הקושחה של המכשיר ונטען באופן אוטומטי בזמן האתחול. הוא פועל רק במצב עבודה מאושר.

מנהל הקריפטו יכול לגרום להרצת הבדיקות העצמיות בכל שלב על ידי הפעלה מחדש של המכשיר.

הנחיות למשתמשים

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

השימוש באלגוריתמים למטרות תאימות ל-FIPS מוגבל לאלגוריתמים שאושרו. כדי לעמוד בדרישת 'מדד השירות' של FIPS 140-3, המודול מספק פונקציה fips140_is_approved_service שמציינת אם אלגוריתם אושר.

שגיאות בבדיקה עצמית

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


  1. צפוי שההטמעות של AES-GCM במודול יהיו 'מאושרות מבחינת האלגוריתם', אבל לא 'מאושרות מבחינת המודול'. אפשר לאמת אותם, אבל אי אפשר להתייחס ל-AES-GCM כאל אלגוריתם מאושר מנקודת המבט של מודול FIPS. הסיבה לכך היא שדרישות המודול של FIPS ל-GCM לא תואמות להטמעות של GCM שלא יוצרות IV משלהם.