מודול קריפטוגרפיה של 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 היה תנאי מוקדם ל-Control Flow Integrity, שהיא תכונת אבטחה חשובה.

לכן, כל הקוד שמכוסה בדרישות של FIPS 140-3 נארז במודול ליבה נפרד fips140.ko שמסתמך רק על ממשקי API יציבים שנחשפים על ידי מקור הליבה של 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 ותיקון חלופות של באגים במעבד בקטעים האלה. כדי לוודא שאפשר לשחזר את התקציר בצורה נכונה, מבצעים את הפעולות הנוספות הבאות:

  • העברות מיקום של ELF נשמרות בתוך המודול כדי שאפשר יהיה להחיל אותן בסדר הפוך על הקלט של ה-HMAC.
  • המודול מבטל את כל תיקוני הקוד שבוצעו על ידי ליבת המערכת עבור Dynamic Shadow Call Stack. באופן ספציפי, המודול מחליף כל הוראה שדוחפת או שולפת מסטאק ביצוע של הצללים בהוראות של קוד אימות המצביע (PAC) שהיו קיימות במקור.
  • כל תיקוני הקוד האחרים מושבתים במודול, כולל מפתחות סטטיים, ולכן גם נקודות מעקב ו-vendor hooks.

מבחנים עצמיים עם תשובות ידועות

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

ב-Linux CryptoAPI יש מושג של עדיפויות אלגוריתמים, שבו יכולות להתקיים כמה הטמעות (למשל, הטמעה אחת שמשתמשת בהוראות קריפטו מיוחדות, והטמעה חלופית למעבדים שלא מטמיעים את ההוראות האלה) של אותו אלגוריתם. לכן, צריך לבדוק את כל ההטמעות של אותו אלגוריתם. הדבר נחוץ כי 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 (תבנית), 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 (תבנית), 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 (תבנית), 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 כן פונקציית גיבוב (hash) קריפטוגרפית SHA-224: הקוד משותף עם SHA-256.
sha256 sha256-generic, sha256-arm64, sha256-ce, ספריית SHA-256 כן פונקציית גיבוב (hash) קריפטוגרפית SHA-256: בנוסף לממשק CryptoAPI הרגיל, יש גם ממשק ספרייה ל-SHA-256. ממשק הספרייה הזה משתמש בהטמעה שונה.
sha384 sha384-generic, sha384-arm64, sha384-ce כן פונקציית גיבוב קריפטוגרפית SHA-384: הקוד משותף עם SHA-512.
sha512 sha512-generic, sha512-arm64, sha512-ce כן פונקציית גיבוב קריפטוגרפי SHA-512
sha3-224 sha3-224-generic כן פונקציית גיבוב קריפטוגרפי 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 באמצעות 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 ממקור באמצעות הפקודות הבאות.

  • פיתוח באמצעות Bazel:

    tools/bazel run //common:fips140_dist
  • בנייה באמצעות build.sh (גרסה קודמת):

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

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

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

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

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

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

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

הדרכה למשתמשים

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

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

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

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


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