ליבת 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 לבדיקה עצמית של אלגוריתם קריפטוגרפי, על ידי הטמעה של בדיקות תשובה ידועה. הבדיקות שהוטמעו משתנות בהתאם לאלגוריתם ועומדות בדרישות של FIPS 140-3 Implementation Guidance 10.3.A.
בדרך כלל, נדרש רק וקטור בדיקה אחד לכל אלגוריתם. הבדיקות העצמיות של אלגוריתם ההצפנה FIPS נועדו לאמת רק פונקציונליות בסיסית. בדיקות מקיפות מתבצעות בנפרד, באמצעות תוכנית האימות של אלגוריתמים קריפטוגרפיים (CAVP) וחבילת מקרים לבדיקה הקריפטוגרפית של ליבת ה-upstream.
כשאלגוריתם כולל כמה הטמעות שהמשתמש יכול לגשת אליהן או שהשירותים של המודול משתמשים בהן, תקן FIPS 140-3 מחייב שכל ההטמעות האלה יעברו בדיקה עצמית. זה רלוונטי לשיטת השילוב שמשמשת בדרך כלל את Linux CryptoAPI, שבה לכל אלגוריתם יכולות להיות כמה הטמעות שמשתמשים יכולים לגשת אליהן. לדוגמה, בקרנל android16-6.12, יש שלוש הטמעות של SHA-256: sha256-generic, sha256-arm64 ו-sha256-ce. במעבדים עם תוספי ההצפנה ARMv8, sha256-ce נמצא בשימוש כברירת מחדל, אבל המשתמשים עדיין יכולים לגשת לתוספים האחרים באופן מפורש. לכן, המודול מבצע בדיקות עצמיות לכל שלושת היישומים.
בליבה android17-6.18 ומעלה, חלק מהאלגוריתמים משתמשים באסטרטגיית שילוב פשוטה יותר. לדוגמה, ב-android17-6.18 kernel, ל-SHA-256 יש הטמעה אחת sha256-lib שבוחרת אוטומטית את הקוד המתאים למעבד בזמן טעינת המודול. לכן, המודול מבצע בדיקה עצמית sha256-lib.
אלגוריתמים שכלולים במודול
כל האלגוריתמים שנכללים במודול FIPS 140-3 מפורטים בהמשך.
המידע הזה רלוונטי לענפי הליבה android12-5.10, android13-5.10, android13-5.15, android14-5.15, android14-6.1, android15-6.6, android16-6.12 ו-android17-6.18, אבל במקומות שבהם יש הבדלים בין גרסאות הליבה, מצוין זאת.
| אלגוריתם | הטמעות | ניתן לאישור | הגדרה |
|---|---|---|---|
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(. ההטמעות האחרות הן עצמאיות. |
ecb(aes) |
ecb (תבנית), ecb-aes-neon, ecb-aes-neonbs, ecb-aes-ce |
כן | AES-ECB: כל הגדלים של מפתחות AES נתמכים. אפשר להשתמש בתבנית ecb עם כל הטמעה של aes באמצעות ecb(. ההטמעות האחרות הן עצמאיות. |
cbc(aes) |
cbc (תבנית), cbc-aes-neon, cbc-aes-neonbs, cbc-aes-ce |
כן | AES-CBC: כל הגדלים של מפתחות AES נתמכים. אפשר להשתמש בתבנית cbc עם כל הטמעה של aes באמצעות cbc(. ההטמעות האחרות הן עצמאיות. |
cts(cbc(aes)) |
cts (תבנית), cts-cbc-aes-neon, cts-cbc-aes-ce |
כן | AES-CBC-CTS או AES-CBC עם גניבת טקסט מוצפן: המוסכמה שבה נעשה שימוש היא CS3; שני הבלוקים האחרונים של הטקסט המוצפן מוחלפים ללא תנאי. כל הגדלים של מפתחות AES נתמכים. אפשר להשתמש בתבנית cts עם כל הטמעה של cbc באמצעות cts(. ההטמעות האחרות הן עצמאיות. |
ctr(aes) |
ctr (תבנית), ctr-aes-neon, ctr-aes-neonbs, ctr-aes-ce |
כן | AES-CTR: כל הגדלים של מפתחות AES נתמכים. אפשר להשתמש בתבנית ctr עם כל הטמעה של aes באמצעות ctr(. ההטמעות האחרות הן עצמאיות. |
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(. ההטמעות האחרות הן עצמאיות. כל ההטמעות מבצעות את בדיקת המפתח החלש שנדרשת על ידי FIPS, כלומר, מפתחות XTS שהחצי הראשון והחצי השני שלהם שווים נדחים. |
gcm(aes) |
gcm (תבנית), gcm-aes-ce |
לא 1 | AES-GCM: כל הגדלים של מפתחות AES נתמכים. יש תמיכה רק ב-IVs של 96 ביט. כמו בכל מצבי ה-AES האחרים במודול הזה, מבצע הקריאה אחראי לספק את ה-IV. אפשר ליצור את התבנית gcm עם כל הטמעה של ctr(aes) ו-ghash באמצעות gcm_base(. ההטמעות האחרות הן עצמאיות. |
sha1 |
גרסה 6.12 ומטה של הליבה: sha1-generic, sha1-ce |
כן | פונקציית הגיבוב הקריפטוגרפי SHA-1. הוסר בליבה 6.18 ומעלה. |
sha224 |
ליבה 6.18 ומעלה: sha224-lib. ליבה 6.12 ומטה: sha224-generic, sha224-arm64, sha224-ce |
כן | פונקציית גיבוב (hash) קריפטוגרפית SHA-224: הקוד משותף עם SHA-256. |
sha256 |
ליבה 6.18 ומעלה: sha256-lib. ליבה 6.12 ומטה: sha256-generic, sha256-arm64, sha256-ce, ספריית SHA-256 |
כן | פונקציית גיבוב (hash) קריפטוגרפית מסוג SHA-256. |
sha384 |
ליבה 6.18 ומעלה: sha384-lib. ליבה 6.12 ומטה: sha384-generic, sha384-arm64, sha384-ce |
כן | פונקציית גיבוב קריפטוגרפית SHA-384: הקוד משותף עם SHA-512. |
sha512 |
ליבה 6.18 ומעלה: sha512-lib. ליבה 6.12 ומטה: sha512-generic, sha512-arm64, sha512-ce |
כן | פונקציית גיבוב קריפטוגרפי SHA-512. |
sha3-224 |
ליבה 6.6 ומעלה: sha3-224-generic |
כן | פונקציית גיבוב קריפטוגרפי SHA3-224. |
sha3-256 |
ליבה 6.6 ומעלה: sha3-256-generic |
כן | אותו דבר כמו הקודם, אבל עם אורך תקציר של 256 ביט (SHA3-256). כל אורכי התקצירים משתמשים באותו יישום של Keccak. |
sha3-384 |
ליבה 6.6 ומעלה: sha3-384-generic |
כן | אותו דבר כמו הקודם, אבל עם אורך תקציר של 384 ביט (SHA3-384). כל אורכי התקצירים משתמשים באותו יישום של Keccak. |
sha3-512 |
ליבה 6.6 ומעלה: sha3-512-generic |
כן | אותו דבר כמו קודם, אבל עם אורך תקציר של 512 ביט (SHA3-512). כל אורכי התקצירים משתמשים באותו יישום של Keccak. |
hmac |
hmac (תבנית) |
כן | קוד אימות הודעות (HMAC) מבוסס-גיבוב (hash): אפשר להשתמש בתבנית hmac עם כל אלגוריתם או הטמעה של SHA באמצעות hmac( או hmac(. |
stdrng |
כל ליבות המערכת: drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512. גרסת ליבה 6.6 ומטה: drbg_pr_hmac_sha1 |
כן | HMAC_DRBG נוצר באמצעות פונקציית הגיבוב שצוינה, עם הפעלת התנגדות לחיזוי: בדיקות תקינות כלולות. למשתמשים בממשק הזה יש מופעי DRBG משלהם. |
stdrng |
כל ליבות המערכת: drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512. גרסת ליבה 6.6 ומטה: drbg_nopr_hmac_sha1 |
כן | זהה לאלגוריתמים של 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) |
ליבה 5.15 ומעלה: xctr-aes-neon, xctr-aes-ce |
לא | |
cbcmac(aes) |
cbcmac-aes-neon, cbcmac-aes-ce |
לא | |
essiv(cbc(aes),sha256) |
essiv-cbc-aes-sha256-neon, essiv-cbc-aes-sha256-ce |
לא |
1. יכול להיות שההטמעות של AES-GCM במודול יאושרו כאלגוריתם אבל לא יאושרו כמודול. אפשר לאמת אותם, אבל אי אפשר להתייחס ל-AES-GCM כאל אלגוריתם מאושר מנקודת המבט של מודול FIPS. הסיבה לכך היא שהדרישות של מודול FIPS עבור GCM לא תואמות להטמעות של GCM שלא יוצרות את ה-IVs שלהן.
בניית המודול מקוד המקור
ב-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 שמציינת אם אלגוריתם מאושר.
שגיאות בבדיקה העצמית
במקרה של כשל בבדיקה העצמית, מודול הליבה גורם לליבה להיכנס למצב פאניקה והמכשיר לא ממשיך אתחול. אם הפעלה מחדש של המכשיר לא פותרת את הבעיה, צריך להפעיל את המכשיר במצב שחזור כדי לתקן את הבעיה על ידי התקנה מחדש של מערכת ההפעלה במכשיר.