जीकेआई कर्नेल में, fips140.ko
नाम का एक Linux कर्नेल मॉड्यूल शामिल होता है. यह क्रिप्टोग्राफ़िक सॉफ़्टवेयर मॉड्यूल के लिए, FIPS 140-3 की ज़रूरी शर्तों का पालन करता है. अगर जीकेआई कर्नेल चलाने वाले प्रॉडक्ट के लिए, FIPS सर्टिफ़िकेशन ज़रूरी है, तो इस मॉड्यूल को सबमिट किया जा सकता है.
क्रिप्टो रूटीन का इस्तेमाल करने से पहले, खास तौर पर FIPS 140-3 की इन शर्तों को पूरा करना ज़रूरी है:
- क्रिप्टोग्राफ़िक एल्गोरिदम उपलब्ध कराने से पहले, मॉड्यूल को अपनी इंटिग्रिटी की जांच करनी होगी.
- मॉड्यूल को, मंज़ूरी पा चुके क्रिप्टोग्राफ़िक एल्गोरिदम का इस्तेमाल करना चाहिए और उनकी पुष्टि करनी चाहिए. इसके लिए, उन्हें उपलब्ध कराने से पहले, ज्ञात जवाब वाले खुद के टेस्ट का इस्तेमाल करना चाहिए.
अलग कर्नेल मॉड्यूल क्यों
FIPS 140-3 की पुष्टि इस आधार पर की जाती है कि एक बार सॉफ़्टवेयर या हार्डवेयर पर आधारित मॉड्यूल को सर्टिफ़िकेट मिल जाने के बाद, उसे कभी नहीं बदला जाता. अगर इसमें बदलाव किया गया है, तो इसका फिर से सर्टिफ़िकेट लेना होगा. यह आज इस्तेमाल की जा रही सॉफ़्टवेयर डेवलपमेंट प्रोसेस से मेल नहीं खाता. इस ज़रूरी शर्त की वजह से, FIPS सॉफ़्टवेयर मॉड्यूल को आम तौर पर क्रिप्टोग्राफ़िक कॉम्पोनेंट पर ज़्यादा से ज़्यादा फ़ोकस करने के लिए डिज़ाइन किया जाता है. इससे यह पक्का किया जा सकता है कि क्रिप्टोग्राफ़ी से जुड़े बदलावों के लिए, क्रिप्टोग्राफ़ी का फिर से आकलन करने की ज़रूरत न पड़े.
जीकेआई कर्नेल को, इसके पूरे लाइफ़टाइम के दौरान नियमित रूप से अपडेट किया जाता है. इस वजह से, पूरे कर्नल को 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
में मॉड्यूल का नाम जोड़ें. इससे मॉड्यूल को वेंडर रैमडिस्क में कॉपी किया जाता है.BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
में मॉड्यूल का नाम जोड़ें. इससे मॉड्यूल का नाम, टारगेट पर मौजूदmodules.load
में जुड़ जाता है.modules.load
में उन मॉड्यूल की सूची होती है जिन्हें डिवाइस बूट होने परinit
लोड करता है.
इंटिग्रिटी की खुद से जांच करने की सुविधा
FIPS 140-3 कर्नल मॉड्यूल, मॉड्यूल लोड होने के समय अपने .code
और .rodata
सेक्शन का एचएमएसी-एसएचए256 डाइजेस्ट लेता है. इसके बाद, इसकी तुलना मॉड्यूल में रिकॉर्ड किए गए डाइजेस्ट से करता है. यह प्रोसेस तब होती है, जब Linux मॉड्यूल लोडर पहले ही सामान्य बदलाव कर चुका होता है. जैसे, उन सेक्शन के लिए ईएलएफ़ रिलोकेशन प्रोसेसिंग और सीपीयू की गड़बड़ियों के लिए ऑल्टरनेटिव पैचिंग. डाइजेस्ट को सही तरीके से फिर से जनरेट किया जा सके, इसके लिए ये अतिरिक्त चरण अपनाए जाते हैं:
- ईएलएफ़ रिलोकेशन को मॉड्यूल में सेव किया जाता है, ताकि उन्हें एचएमएसी के इनपुट पर उलटे क्रम में लागू किया जा सके.
- यह मॉड्यूल, कर्नल के ज़रिए Dynamic Shadow Call Stack के लिए किए गए सभी कोड पैच को पहले जैसा कर देता है. खास तौर पर, यह मॉड्यूल शैडो कॉल स्टैक से पुश या पॉप करने वाले किसी भी निर्देश को, मूल रूप से मौजूद पॉइंटर ऑथेंटिकेशन कोड (पीएसी) निर्देशों से बदल देता है.
- मॉड्यूल के लिए, कोड में किए जाने वाले अन्य सभी बदलाव बंद कर दिए जाते हैं. इनमें स्टैटिक कुंजियां और इसलिए ट्रेसपॉइंट के साथ-साथ वेंडर हुक भी शामिल हैं.
जवाब पहले से पता होने वाले सवालों के लिए खुद से टेस्ट करने की सुविधा
FIPS 140-3 की ज़रूरी शर्तों के दायरे में आने वाले सभी लागू किए गए एल्गोरिदम को इस्तेमाल करने से पहले, ज्ञात जवाब वाला सेल्फ़ टेस्ट करना होगा. FIPS 140-3 Implementation Guidance 10.3.A के मुताबिक, साइफ़र के लिए, इस्तेमाल की जा सकने वाली किसी भी कुंजी की लंबाई का इस्तेमाल करके, हर एल्गोरिदम के लिए एक टेस्ट वेक्टर काफ़ी होता है. हालांकि, यह तब तक मान्य है, जब तक एन्क्रिप्शन और डिक्रिप्शन, दोनों की जांच न कर ली जाए.
Linux CryptoAPI में एल्गोरिदम की प्राथमिकताएं तय की जाती हैं. इसमें एक ही एल्गोरिदम के कई वर्शन एक साथ काम कर सकते हैं. जैसे, एक वर्शन में खास क्रिप्टोग्राफ़िक निर्देशों का इस्तेमाल किया जाता है और दूसरे वर्शन में उन सीपीयू के लिए फ़ॉलबैक का इस्तेमाल किया जाता है जो उन निर्देशों को लागू नहीं करते. इसलिए, एक ही एल्गोरिदम के सभी वर्शन की जाँच करना ज़रूरी है. यह ज़रूरी है, क्योंकि 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 ब्लॉक साइफ़र: सभी कुंजी साइज़ (128 बिट, 192 बिट, और 256 बिट) काम करते हैं. लाइब्रेरी को लागू करने के अलावा, अन्य सभी तरीकों को टेम्प्लेट के ज़रिए ऑपरेशन के मोड के साथ कंपोज़ किया जा सकता है. |
cmac(aes) |
cmac (टेंप्लेट), cmac-aes-neon , cmac-aes-ce |
हां | AES-CMAC: इसमें एईएस के सभी साइज़ की कुंजियां इस्तेमाल की जा सकती हैं. cmac टेंप्लेट को cmac(<aes-impl>) का इस्तेमाल करके, aes के किसी भी वर्शन के साथ कंपोज़ किया जा सकता है. अन्य लागू करने के तरीके, स्टैंडअलोन होते हैं. |
ecb(aes) |
ecb (टेंप्लेट), ecb-aes-neon , ecb-aes-neonbs , ecb-aes-ce |
हां | AES-ECB: इसमें AES के सभी साइज़ की कुंजियां इस्तेमाल की जा सकती हैं. ecb टेंप्लेट को ecb(<aes-impl>) का इस्तेमाल करके, aes के किसी भी वर्शन के साथ कंपोज़ किया जा सकता है. अन्य लागू करने के तरीके, स्टैंडअलोन होते हैं. |
cbc(aes) |
cbc (टेंप्लेट), cbc-aes-neon , cbc-aes-neonbs , cbc-aes-ce |
हां | AES-CBC: इसमें AES के सभी साइज़ की कुंजियां इस्तेमाल की जा सकती हैं. cbc टेंप्लेट को ctr(<aes-impl>) का इस्तेमाल करके, aes के किसी भी वर्शन के साथ कंपोज़ किया जा सकता है. अन्य लागू करने के तरीके, स्टैंडअलोन होते हैं. |
cts(cbc(aes)) |
cts (टेंप्लेट), cts-cbc-aes-neon , cts-cbc-aes-ce |
हां | AES-CBC-CTS या AES-CBC with ciphertext stealing: इसमें CS3 का इस्तेमाल किया जाता है. साथ ही, आखिरी दो साइफ़रटेक्स्ट ब्लॉक को बिना किसी शर्त के स्वैप किया जाता है. एईएस के सभी साइज़ की कुंजियां इस्तेमाल की जा सकती हैं. cts टेंप्लेट को cts(<cbc(aes)-impl>) का इस्तेमाल करके, cbc के किसी भी वर्शन के साथ कंपोज़ किया जा सकता है. अन्य लागू करने के तरीके, स्टैंडअलोन होते हैं. |
ctr(aes) |
ctr (टेंप्लेट), ctr-aes-neon , ctr-aes-neonbs , ctr-aes-ce |
हां | AES-CTR: इसमें एईएस के सभी साइज़ की कुंजियां इस्तेमाल की जा सकती हैं. ctr टेंप्लेट को ctr(<aes-impl>) का इस्तेमाल करके, aes के किसी भी वर्शन के साथ कंपोज़ किया जा सकता है. अन्य लागू करने के तरीके, स्टैंडअलोन होते हैं. |
xts(aes) |
xts (टेंप्लेट), xts-aes-neon , xts-aes-neonbs , xts-aes-ce |
हां | AES-XTS: कर्नेल के 6.1 और इससे पहले के वर्शन में, AES की सभी साइज़ वाली कुंजियों का इस्तेमाल किया जा सकता है. कर्नेल के 6.6 और इसके बाद के वर्शन में, सिर्फ़ AES-128 और AES-256 का इस्तेमाल किया जा सकता है. xts टेंप्लेट को xts(<ecb(aes)-impl>) का इस्तेमाल करके, ecb(aes) के किसी भी वर्शन के साथ कंपोज़ किया जा सकता है. अन्य लागू करने के तरीके, स्टैंडअलोन होते हैं. सभी लागू करने वाले, FIPS के लिए ज़रूरी कमज़ोर कुंजी की जांच को लागू करते हैं. इसका मतलब है कि XTS कुंजियों के पहले और दूसरे हिस्से बराबर होने पर उन्हें अस्वीकार कर दिया जाता है. |
gcm(aes) |
gcm (टेंप्लेट), gcm-aes-ce |
नहीं1 | AES-GCM: इसमें एईएस की सभी साइज़ वाली कुंजियां काम करती हैं. सिर्फ़ 96-बिट IV इस्तेमाल किए जा सकते हैं. इस मॉड्यूल में मौजूद अन्य सभी एईएस मोड की तरह, कॉल करने वाले व्यक्ति की ज़िम्मेदारी है कि वह IV उपलब्ध कराए. gcm_base(<ctr(aes)-impl>,<ghash-impl>) का इस्तेमाल करके, gcm टेंप्लेट को ctr(aes) और ghash के किसी भी वर्शन के साथ कंपोज़ किया जा सकता है. अन्य लागू करने के तरीके, स्टैंडअलोन होते हैं. |
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
मॉड्यूल के साथ-साथ पूरा बिल्ड तैयार होता है. इसमें एचएमएसी-एसएचए256 डाइजेस्ट कॉन्टेंट एम्बेड किया जाता है.
असली उपयोगकर्ता के लिए दिशा-निर्देश
क्रिप्टो ऑफ़िसर के लिए दिशा-निर्देश
कर्नल मॉड्यूल को चलाने के लिए, ऑपरेटिंग सिस्टम को सिर्फ़ एक ऑपरेटर मोड में काम करने की अनुमति होनी चाहिए. इसे Android अपने-आप मैनेज करता है. इसके लिए, प्रोसेसर में मौजूद मेमोरी मैनेजमेंट हार्डवेयर का इस्तेमाल किया जाता है.
कर्नेल मॉड्यूल को अलग से इंस्टॉल नहीं किया जा सकता. यह डिवाइस के फ़र्मवेयर का हिस्सा होता है और बूट होने पर अपने-आप लोड हो जाता है. यह सिर्फ़ मंज़ूरी वाले मोड में काम करता है.
क्रिप्टो ऑफ़िसर, डिवाइस को रीस्टार्ट करके किसी भी समय सेल्फ़-टेस्ट चला सकता है.
उपयोगकर्ता के लिए निर्देश
कर्नल मॉड्यूल का इस्तेमाल करने वाले उपयोगकर्ता, कर्नल के अन्य कॉम्पोनेंट होते हैं. इन कॉम्पोनेंट को क्रिप्टोग्राफ़िक एल्गोरिदम का इस्तेमाल करना होता है. कर्नल मॉड्यूल, एल्गोरिदम के इस्तेमाल में कोई अतिरिक्त लॉजिक नहीं देता. साथ ही, यह क्रिप्टोग्राफ़िक ऑपरेशन करने के लिए ज़रूरी समय के बाद कोई पैरामीटर सेव नहीं करता.
FIPS के नियमों का पालन करने के लिए, एल्गोरिदम का इस्तेमाल सिर्फ़ उन एल्गोरिदम तक सीमित है जिन्हें मंज़ूरी मिली है. FIPS 140-3 "सेवा इंडिकेटर" की ज़रूरी शर्त को पूरा करने के लिए, मॉड्यूल एक फ़ंक्शन fips140_is_approved_service
उपलब्ध कराता है. यह फ़ंक्शन बताता है कि किसी एल्गोरिदम को मंज़ूरी मिली है या नहीं.
सेल्फ़ टेस्ट से जुड़ी गड़बड़ियां
सेल्फ़ टेस्ट फ़ेल होने पर, कर्नेल मॉड्यूल की वजह से कर्नेल पैनिक हो जाता है और डिवाइस बूट नहीं होता. अगर डिवाइस को रीबूट करने से समस्या हल नहीं होती है, तो डिवाइस को रिकवरी मोड में बूट करना होगा. इससे डिवाइस को फिर से फ़्लैश करके समस्या को ठीक किया जा सकता है.
-
उम्मीद है कि मॉड्यूल के AES-GCM को "एल्गोरिदम के तौर पर मंज़ूरी" मिल सकती है, लेकिन "मॉड्यूल के तौर पर मंज़ूरी" नहीं मिल सकती. इनकी पुष्टि की जा सकती है, लेकिन AES-GCM को FIPS मॉड्यूल के हिसाब से, मंज़ूरी पा चुका एल्गोरिदम नहीं माना जा सकता. ऐसा इसलिए है, क्योंकि GCM के लिए FIPS मॉड्यूल की ज़रूरी शर्तें, GCM के उन इंप्लीमेंटेशन के साथ काम नहीं करती हैं जो अपने IV जनरेट नहीं करते हैं. ↩