ליבת 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 |
כן | פונקציית גיבוב (hash) קריפטוגרפית 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
מהמקור באמצעות הפקודות הבאות.
גרסת build עם 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
שמציינת אם אלגוריתם מאושר.
שגיאות בבדיקה העצמית
במקרה של כשל בבדיקה העצמית, מודול הליבה גורם לליבה להיכנס למצב פאניקה והמכשיר לא ממשיך אתחול. אם הפעלה מחדש של המכשיר לא פותרת את הבעיה, צריך להפעיל את המכשיר במצב שחזור כדי לתקן את הבעיה על ידי צריבת קושחה מחדש במכשיר.
-
ההנחה היא שההטמעות של AES-GCM במודול יכולות להיות 'מאושרות על ידי האלגוריתם' אבל לא 'מאושרות על ידי המודול'. אפשר לאמת אותם, אבל אי אפשר להחשיב את AES-GCM כאלגוריתם מאושר מנקודת המבט של מודול FIPS. הסיבה לכך היא שהדרישות של מודול FIPS עבור GCM לא תואמות להטמעות של GCM שלא יוצרות את ה-IVs שלהן. ↩