מודול הצפנה 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 של הליבה (kernel) היה שיקול נוסף שהייתם מוסיפים ל-GKI עם LTO (אופטימיזציה של זמן קישור), כי LTO הייתה דרישה מוקדמת לControl Integrity, שהיא תכונת אבטחה חשובה.

לכן, כל הקוד שמכוסה בדרישות של 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 לוקח את התקציר SHA256 של מקטעי .code ו-.rodata שלו בזמן הטעינה של המודול, ומשווה אותו לתקציר שתועד במודול. הפעולה הזו מתרחשת אחרי שטוען המודול של Linux כבר ביצע את השינויים הרגילים, כמו עיבוד המיקום של ELF ותיקון חלופות לשגיאות במעבד (CPU) בקטעים האלה. כדי לוודא שאפשר לשחזר את התקציר בצורה נכונה, צריך גם לבצע את הפעולות הבאות:

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

התשובות העצמיות הידועות

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

ל-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 עם גניבת מידע מוצפן (ciphertext): המוסכמה שבה נעשה שימוש היא CS3. שני הבלוקים האחרונים של מידע מוצפן (ciphertext) מוחלפים ללא תנאי.יש תמיכה בכל הגדלים של מפתחות 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 יש תמיכה בכל הגדלים של מפתחות 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 כן פונקציית גיבוב (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
sha3-224 sha3-224-generic כן פונקציית גיבוב (hash) קריפטוגרפית מסוג SHA3-224. קיים רק בגרסת ליבה (kernel) 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 (קוד אימות הודעות עם גיבוב (Keyed-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 נוצר באמצעות פונקציית גיבוב בעלת שם ועם עמידות לחיזוי מופעלת: בדיקות תקינות נכללות. למשתמשים בממשק הזה יש מכונות 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 ואילך של ליבה). למשתמשים בממשק הזה יש מכונות RNG משלהם. הם לא עושים שימוש חוזר במכונות שבהן נעשה שימוש ב-DRBG.
xcbc(aes) xcbc-aes-neon, xcbc-aes-ce לא
xctr(aes) xctr-aes-neon, xctr-aes-ce לא קיים רק בגרסת ליבה (kernel) 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 באמצעות 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 שמציינת אם אלגוריתם אושר.

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

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


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