FIPS 140-3 โมดูลการเข้ารหัส GKI ที่ผ่านการรับรอง

เคอร์เนล GKI มีโมดูลเคอร์เนล Linux ชื่อ fips140.ko ซึ่งเป็นไปตามข้อกำหนด FIPS 140-3 สำหรับโมดูลซอฟต์แวร์เข้ารหัส โมดูลนี้สามารถส่งเพื่อรับการรับรอง FIPS ได้ หากผลิตภัณฑ์ที่ใช้เคอร์เนล GKI จำเป็นต้องใช้

ต้องปฏิบัติตามข้อกำหนด FIPS 140-3 ต่อไปนี้เป็นพิเศษก่อนที่จะใช้รูทีนการเข้ารหัสลับ:

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

ทำไมต้องแยกโมดูลเคอร์เนล

การตรวจสอบ FIPS 140-3 ขึ้นอยู่กับแนวคิดที่ว่าเมื่อโมดูลที่ใช้ซอฟต์แวร์หรือฮาร์ดแวร์ได้รับการรับรองแล้ว จะไม่มีการเปลี่ยนแปลงใดๆ หากมีการเปลี่ยนแปลงจะต้องได้รับการรับรองซ้ำ สิ่งนี้ไม่ตรงกับกระบวนการพัฒนาซอฟต์แวร์ที่ใช้อยู่ในปัจจุบัน และจากข้อกำหนดนี้ โดยทั่วไปโมดูลซอฟต์แวร์ FIPS จึงได้รับการออกแบบมาให้เน้นที่ส่วนประกอบการเข้ารหัสอย่างแน่นหนาที่สุดเท่าที่จะเป็นไปได้ เพื่อให้แน่ใจว่าการเปลี่ยนแปลงที่ไม่เกี่ยวข้องกับการเข้ารหัสจะทำได้ ไม่จำเป็นต้องประเมินการเข้ารหัสอีกครั้ง

เคอร์เนล GKI มีวัตถุประสงค์เพื่อให้อัปเดตเป็นประจำตลอดอายุการใช้งานที่รองรับ ซึ่งทำให้เป็นไปไม่ได้ที่เคอร์เนลทั้งหมดจะอยู่ภายในขอบเขตโมดูล FIPS เนื่องจากโมดูลดังกล่าวจะต้องได้รับการรับรองซ้ำทุกครั้งที่มีการอัพเดตเคอร์เนล การกำหนด "โมดูล FIPS" ให้เป็นชุดย่อยของเคอร์เนลอิมเมจจะช่วยบรรเทาปัญหานี้ได้ แต่จะไม่สามารถแก้ปัญหาได้ เนื่องจากเนื้อหาไบนารีของ "โมดูล FIPS" จะยังคงเปลี่ยนแปลงบ่อยเกินความจำเป็น

ก่อนเคอร์เนลเวอร์ชัน 6.1 ข้อควรพิจารณาอีกประการหนึ่งคือ GKI ได้รับการคอมไพล์โดยเปิดใช้งาน LTO (Link Time Optimization) เนื่องจาก 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 ของตัวเอง ณ เวลาโหลดโมดูล และเปรียบเทียบกับการแยกย่อยที่บันทึกไว้ในโมดูล สิ่งนี้จะเกิดขึ้นหลังจากที่ตัวโหลดโมดูล Linux ได้ทำการแก้ไขตามปกติแล้ว เช่น การประมวลผลการย้ายตำแหน่ง ELF และการแพตช์ทางเลือกสำหรับข้อผิดพลาดของ CPU ไปยังส่วนเหล่านั้น มีการดำเนินการขั้นตอนเพิ่มเติมต่อไปนี้เพื่อให้แน่ใจว่าสามารถทำซ้ำการย่อยได้อย่างถูกต้อง:

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

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

อัลกอริธึมที่นำไปใช้ใดๆ ที่ครอบคลุมโดยข้อกำหนด FIPS 140-3 จะต้องดำเนินการทดสอบตัวเองที่ทราบคำตอบก่อนที่จะนำไปใช้ ตาม FIPS 140-3 Implementation Guidance 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 แม้ว่าความแตกต่างระหว่างเวอร์ชันเคอร์เนลจะถูกบันทึกไว้ตามความเหมาะสม

อัลกอริทึม การดำเนินการ อนุมัติได้ คำนิยาม
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 ทั้งหมด รองรับ 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
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 : ผู้ใช้อินเทอร์เฟซนี้จะได้รับอินสแตนซ์ 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 ฝังอยู่ในนั้น

คำแนะนำสำหรับผู้ใช้ปลายทาง

คำแนะนำของเจ้าหน้าที่ Crypto

ในการใช้งานโมดูลเคอร์เนล ระบบปฏิบัติการจะต้องถูกจำกัดให้อยู่ในโหมดการทำงานของผู้ปฏิบัติงานเพียงคนเดียว สิ่งนี้ได้รับการจัดการโดยอัตโนมัติโดย Android โดยใช้ฮาร์ดแวร์การจัดการหน่วยความจำในโปรเซสเซอร์

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

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

คำแนะนำผู้ใช้

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

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

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

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


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