הליבה של 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.
- המודול מבטל את תיקוני הקוד שנוצרו על ידי הליבה עבור 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 (תבנית), 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: בגרסאות ליבה (kernel) 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 שבמודול הזה, מבצע הקריאה החוזרת (caller) אחראי לספק את ה-IVs. אפשר ליצור את התבנית 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 . בגרסת ליבה (kernel) 5.15 ואילך היא drbg_pr_hmac_sha512 . |
jitterentropy_rng |
jitterentropy_rng |
לא | Jitter RNG, גרסה 2.2.0 (גרסת ליבה 6.1 ומטה) או גרסה 3.4.0 (גרסת ליבה 6.6 ומעלה). משתמשים בממשק הזה מקבלים מכונות Jitter RNG משלהם. הם לא משתמשים שוב במכונות שבהן ה-DRBGs משתמשים. |
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
, עם תוכן התקציר SHA256 שמוטמע בו.
הנחיות למשתמשי קצה
הנחיות לקצין קריפטו
כדי להפעיל את מודול הליבה, מערכת ההפעלה צריכה להיות מוגבלת למצב הפעלה של מפעיל יחיד. מערכת Android מטפלת בכך באופן אוטומטי באמצעות חומרה לניהול זיכרון במעבד.
לא ניתן להתקין את מודול הליבה בנפרד. הוא נכלל כחלק מתוכנת הקושחה של המכשיר ונטען באופן אוטומטי בזמן האתחול. הוא פועל רק במצב עבודה מאושר.
מנהל האבטחה יכול להפעיל את הבדיקות העצמיות בכל שלב על ידי הפעלה מחדש של המכשיר.
הנחיות למשתמשים
משתמש מודול הליבה הוא רכיבים אחרים בליבה שצריכים להשתמש באלגוריתם קריפטוגרפיים. מודול הליבה לא מספק לוגיקה נוספת לשימוש באלגוריתמים, ולא מאחסן פרמטרים מעבר לזמן הנדרש לביצוע פעולה קריפטוגרפית.
השימוש באלגוריתמים למטרות תאימות ל-FIPS מוגבל לאלגוריתמים שאושרו. כדי לעמוד בדרישת 'מדד השירות' של FIPS 140-3, המודול מספק פונקציה fips140_is_approved_service
שמציינת אם אלגוריתם אושר.
שגיאות בבדיקה עצמית
אם הבדיקה העצמית נכשלת, מודול הליבה גורם לליבה להיכנס למצב חרדה והמכשיר לא ממשיך את האתחול. אם הפעלה מחדש של המכשיר לא פותרת את הבעיה, צריך להפעיל את המכשיר במצב שחזור כדי לתקן את הבעיה באמצעות מחיקת נתונים והפעלה מחדש (flash) של המכשיר.
-
צפוי שההטמעות של AES-GCM במודול יהיו 'מאושרות מבחינת האלגוריתם', אבל לא 'מאושרות מבחינת המודול'. אפשר לאמת אותם, אבל אי אפשר להתייחס ל-AES-GCM כאל אלגוריתם מאושר מנקודת המבט של מודול FIPS. הסיבה לכך היא שהדרישות של מודול FIPS ל-GCM לא תואמות להטמעות של GCM שלא יוצרות מערכות IV אחרות. ↩