โมดูลการเข้ารหัส 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 ซึ่งจะทำให้ระบบคัดลอกโมดูลไปยัง 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 กล่าวคือ โมดูลจะแทนที่คำสั่งใดก็ตามที่ พุชหรือป็อปจากสแต็กการเรียกแบบเงาด้วยคำสั่งรหัสการตรวจสอบสิทธิ์พอยน์เตอร์ (PAC) ที่มีอยู่เดิม
  • การแก้ไขโค้ดอื่นๆ ทั้งหมดจะปิดใช้สำหรับโมดูล ซึ่งรวมถึงคีย์แบบคงที่และ จุดติดตาม ตลอดจนฮุกของผู้ให้บริการ

การทดสอบด้วยตนเองที่ทราบคำตอบ

อัลกอริทึมที่ใช้งานซึ่งครอบคลุมข้อกำหนด FIPS 140-3 ต้อง ทำการทดสอบตัวเองด้วยคำตอบที่ทราบก่อนใช้งาน ตามคำแนะนำในการติดตั้งใช้งาน FIPS 140-3 10.3.A เวกเตอร์การทดสอบเดียวต่ออัลกอริทึมโดยใช้ความยาวคีย์ที่รองรับ ก็เพียงพอสำหรับไซเฟอร์ ตราบใดที่ได้ทดสอบทั้งการเข้ารหัสและการถอดรหัส

CryptoAPI ของ Linux มีแนวคิดเรื่องลำดับความสำคัญของอัลกอริทึม ซึ่งการใช้งานอัลกอริทึมเดียวกันหลายแบบ (เช่น แบบที่ใช้คำสั่งการเข้ารหัสพิเศษ และแบบสำรองสำหรับ 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 บิต เช่นเดียวกับโหมด AES อื่นๆ ทั้งหมดในโมดูลนี้ ผู้เรียกใช้มีหน้าที่รับผิดชอบในการระบุ IV 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 (รหัสการตรวจสอบสิทธิ์ข้อความแฮชที่มีการคีย์): 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 จะจัดการเรื่องนี้โดยอัตโนมัติ โดยใช้ฮาร์ดแวร์การจัดการหน่วยความจำในโปรเซสเซอร์

คุณติดตั้งโมดูลเคอร์เนลแยกต่างหากไม่ได้ โดยโมดูลนี้จะรวมอยู่ใน เฟิร์มแวร์ของอุปกรณ์และโหลดโดยอัตโนมัติเมื่อบูต โดยจะทำงานใน โหมดการทำงานที่ได้รับอนุมัติเท่านั้น

เจ้าหน้าที่ดูแลด้านการเข้ารหัสสามารถทำให้ระบบเรียกใช้การทดสอบด้วยตนเองได้ทุกเมื่อโดยการรีสตาร์ท อุปกรณ์

คำแนะนำสำหรับผู้ใช้

ผู้ใช้โมดูลเคอร์เนลคือคอมโพเนนต์เคอร์เนลอื่นๆ ที่ต้องใช้อัลกอริทึมการเข้ารหัส โมดูลเคอร์เนลไม่ได้มีตรรกะเพิ่มเติมในการใช้อัลกอริทึม และไม่ได้จัดเก็บพารามิเตอร์ใดๆ นอกเหนือจากเวลาที่จำเป็นในการดำเนินการเข้ารหัสลับ

การใช้อัลกอริทึมเพื่อวัตถุประสงค์ในการปฏิบัติตามข้อกำหนดของ FIPS จะจำกัดเฉพาะอัลกอริทึมที่ได้รับอนุมัติ โมดูลมีฟังก์ชัน fips140_is_approved_service ที่ระบุว่าอัลกอริทึมได้รับอนุมัติหรือไม่ เพื่อให้เป็นไปตามข้อกำหนด "ตัวบ่งชี้บริการ" ของ FIPS 140-3

ข้อผิดพลาดในการทดสอบด้วยตนเอง

ในกรณีที่การทดสอบด้วยตนเองล้มเหลว โมดูลเคอร์เนลจะทำให้เคอร์เนล หยุดทำงานและอุปกรณ์จะไม่บูตต่อ หากการรีบูตอุปกรณ์ไม่ช่วยแก้ปัญหา คุณต้องบูตอุปกรณ์เข้าสู่โหมดการกู้คืนเพื่อแก้ไขปัญหาโดยการแฟลชอุปกรณ์อีกครั้ง


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