เคอร์เนล 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
ที่ระบุว่าอัลกอริทึมได้รับการอนุมัติหรือไม่
ข้อผิดพลาดในการทดสอบตัวเอง
ในกรณีที่การทดสอบตัวเองล้มเหลว โมดูลเคอร์เนลจะทำให้เคอร์เนลตื่นตระหนกและอุปกรณ์ไม่สามารถบู๊ตต่อได้ หากการรีบูตอุปกรณ์ไม่สามารถแก้ไขปัญหาได้ อุปกรณ์จะต้องบูตเข้าสู่โหมดการกู้คืนเพื่อแก้ไขปัญหาด้วยการแฟลชอุปกรณ์อีกครั้ง
คาดว่าการใช้งาน AES-GCM ของโมดูลสามารถ "อนุมัติอัลกอริทึม" ได้ แต่ไม่ใช่ "อนุมัติโมดูล" สามารถตรวจสอบได้ แต่ AES-GCM ไม่สามารถถือเป็นอัลกอริธึมที่ได้รับอนุมัติจากจุดยืนของโมดูล FIPS เนื่องจากข้อกำหนดของโมดูล FIPS สำหรับ GCM เข้ากันไม่ได้กับการใช้งาน GCM ที่ไม่ได้สร้าง IV ของตนเอง ↩