מודול קריפטו GKI בר אישור FIPS 140-3

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

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

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

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

כיצד לפרוס את המודול

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

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

בדיקת תקינות עצמית

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

  • העברות ELF נשמרות בתוך המודול כך שניתן ליישם אותן הפוך לקלט של ה-HMAC.
  • כל תיקון קוד אחר מושבת עבור המודול, כולל מפתחות סטטיים ולכן נקודות עקיבה כמו גם ווים של ספקים.

הבדיקות העצמיות המוכרות

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

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

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

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

אַלגוֹרִיתְם יישומים ניתן לאישור הַגדָרָה
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: כל גדלי מפתחות AES נתמכים. תבנית 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 כן פונקציית Hash קריפטוגרפית 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: ממשק ספרייה מסופק ל-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
hmac hmac (תבנית) כן HMAC (קוד אימות הודעות מפתח-Hash): ניתן להרכיב את תבנית 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 מופעלת עם פונקציית ה-hash הנקראת ועם התנגדות חיזוי מופעלת: בדיקות תקינות כלולות. משתמשים בממשק זה מקבלים מופעי 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 לא גרסה 2.2.0 של Jitter RNG : משתמשים בממשק זה מקבלים מופעי 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 לא

בנה את המודול ממקור

עבור אנדרואיד 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 מוטבע בו.

הדרכה למשתמש קצה

הדרכה לקצין קריפטו

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

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

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

הדרכה למשתמש

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

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

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

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


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