โมดูลการเข้ารหัส 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 มีการพิจารณาอีกประการหนึ่งคือ 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 เพื่อแก้ไขโดยการแฟลชอุปกรณ์อีกครั้ง


  1. คาดว่าการติดตั้งใช้งาน AES-GCM ของโมดูลอาจเป็น "อัลกอริทึม" อนุมัติแล้ว" แต่ไม่ใช่ "อนุมัติโมดูลแล้ว" ซึ่งสามารถตรวจสอบได้ แต่ AES-GCM ไม่สามารถถือว่าเป็นอัลกอริทึมที่ได้รับการอนุมัติจากมุมมองของโมดูล FIPS เนื่องจากข้อกำหนดของโมดูล FIPS สำหรับ GCM ไม่สามารถทำงานร่วมกับ การติดตั้งใช้งาน GCM ที่ไม่ได้สร้าง IV ของตนเอง