เคอร์เนล 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 นอกจากนี้ โมดูลดังกล่าวไม่มีความสามารถเพิ่มเติมใดๆ และอาจส่งผลต่อเวลาในการบูตโดยไม่ให้ประโยชน์ใดๆ
วิธีทำให้โมดูลใช้งานได้
คุณรวมโมดูลไว้ในบิลด์ Android ได้โดยทำตามขั้นตอนต่อไปนี้
- เพิ่มชื่อโมดูลลงใน
BOARD_VENDOR_RAMDISK_KERNEL_MODULES
ซึ่งทำให้ ที่จะคัดลอกไปยัง RAM ของผู้ให้บริการ - เพิ่มชื่อโมดูลใน
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
ช่วงเวลานี้ จะทำให้มีการเพิ่มชื่อโมดูลไปยังmodules.load
ในเป้าหมายmodules.load
เก็บรายการโมดูลที่init
โหลดเมื่ออุปกรณ์บูต
การตรวจสอบความสมบูรณ์ด้วยตนเอง
โมดูลเคอร์เนล FIPS 140-3 ใช้ไดเจสต์ HMAC-SHA256 ของตนเอง .code
และ .rodata
ส่วนที่ใช้เวลาในการโหลดโมดูล แล้วนำไปเปรียบเทียบกับไดเจสต์
ที่บันทึกไว้ในโมดูล ซึ่งจะเกิดขึ้นหลังจากที่ตัวโหลดโมดูล Linux มี
ได้ทำการแก้ไขตามปกติแล้ว เช่น การประมวลผลการย้าย ELF และ
ทางเลือกต่างๆ ในการแพตช์ข้อผิดพลาด CPU ของส่วนเหล่านั้น ดังต่อไปนี้
ดำเนินการตามขั้นตอนเพิ่มเติมเพื่อให้แน่ใจว่าสร้างไดเจสต์ซ้ำได้
อย่างถูกต้อง:
- ระบบจะเก็บการย้ายตำแหน่ง ELF ไว้ภายในโมดูลเพื่อให้ใช้ย้อนกลับกับอินพุตของ HMAC ได้
- โมดูลจะเปลี่ยนแพตช์โค้ดที่เคอร์เนลสร้างขึ้นสำหรับสแต็กการเรียกแบบไดนามิก กล่าวโดยละเอียดคือ โมดูลจะแทนที่คำสั่งที่ดันหรือป๊อปจากกองคิวการเรียก Shadow ด้วยคำสั่งรหัสการตรวจสอบ Pointer (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 (เทมเพลต) 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 โดยระบบจะสลับบล็อกข้อความที่เข้ารหัส 2 บล็อกสุดท้ายโดยไม่มีเงื่อนไขรองรับคีย์ 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 ทั้งหมด รองรับเฉพาะ IV 96 บิตเท่านั้น ผู้เรียกมีหน้าที่ระบุ IV เช่นเดียวกับโหมด AES อื่นๆ ทั้งหมดในโมดูลนี้ เทมเพลต 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 |
ใช่ | ฟังก์ชันแฮชการเข้ารหัสลับ 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 (Keyed-Hash Message Authentication Code): เทมเพลต 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
จากซอร์สโค้ดโดยใช้คําสั่งต่อไปนี้
สร้างด้วย 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 จะจัดการเรื่องนี้โดยอัตโนมัติโดยใช้ฮาร์ดแวร์การจัดการหน่วยความจำในโปรเซสเซอร์
โมดูลเคอร์เนลจะติดตั้งแยกต่างหากไม่ได้ เนื่องจากรวมอยู่ในเฟิร์มแวร์ของอุปกรณ์และโหลดโดยอัตโนมัติเมื่อบูต โดยดำเนินการเฉพาะใน โหมดการทำงานที่อนุมัติ
Crypto Officer สามารถทำให้การทดสอบด้วยตนเองดำเนินการได้ทุกเมื่อโดยการรีสตาร์ท อุปกรณ์
คำแนะนำสำหรับผู้ใช้
ผู้ใช้โมดูลเคอร์เนลเป็นคอมโพเนนต์เคอร์เนลอื่นๆ ที่ต้องใช้ ของอัลกอริทึมการเข้ารหัส โมดูลเคอร์เนลไม่ได้ให้ตรรกะเพิ่มเติมใน ใช้อัลกอริทึม และไม่จัดเก็บพารามิเตอร์ใดๆ นอกเหนือจากช่วงเวลา ที่จำเป็นต่อการดำเนินการเข้ารหัส
การใช้อัลกอริทึมเพื่อวัตถุประสงค์ในการปฏิบัติตามข้อกำหนดของ FIPS จำกัดไว้เฉพาะที่ได้รับอนุมัติ
อัลกอริทึม เพื่อให้เป็นไปตาม FIPS 140-3 "ตัวบ่งชี้การให้บริการ"
โมดูลจะมีฟังก์ชัน fips140_is_approved_service
ที่บ่งชี้ว่า
อัลกอริทึมได้รับอนุมัติ
ข้อผิดพลาดในการทดสอบตนเอง
ในกรณีที่การทดสอบตนเองล้มเหลว โมดูลเคอร์เนลจะทำให้เคอร์เนล และเปิดอุปกรณ์ไม่ยอมเปิดเครื่อง หากการรีบูตอุปกรณ์ไม่ช่วยแก้ปัญหาได้ อุปกรณ์จะต้องบูตเข้าสู่ Recovery Mode เพื่อแก้ไขโดยการแฟลชอุปกรณ์อีกครั้ง
-
คาดว่าการติดตั้งใช้งาน AES-GCM ของโมดูลอาจเป็น "อัลกอริทึม" อนุมัติแล้ว" แต่ไม่ใช่ "อนุมัติโมดูลแล้ว" ซึ่งสามารถตรวจสอบได้ แต่ AES-GCM ไม่สามารถถือว่าเป็นอัลกอริทึมที่ได้รับการอนุมัติจากมุมมองของโมดูล FIPS เนื่องจากข้อกำหนดของโมดูล FIPS สำหรับ GCM ไม่สามารถทำงานร่วมกับ การติดตั้งใช้งาน GCM ที่ไม่ได้สร้าง IV ของตนเอง ↩