プログラミング
Golang: Crypto/fips140: cryptoコードを不必要に肥大化させない
Golang: Crypto/fips140: do not bloat crypto code unnecessarily (github.com)
要約
GoのFIPS140コード、特にその乱数生成器(RNG)は、ほとんどのGoバイナリで未使用かつ肥大化しています。この提案は、未使用のFIPSコードをコンパイルしないように、新しいデフォルト値GOFIPS140=disabledを追加することです。これにより、バイナリのサイズが削減され、不要なコードのコンパイルや初期化によるメモリやディスク容量の無駄遣いがなくなります。
全文翻訳
golang / go
公開
通知
通知設定を変更するにはサインインする必要があります
Fork 21.1k
Star 139k
proposal: crypto/fips140: do not bloat crypto code unnecessarily #81639
新しいイシュー
リンクをコピー
新しいイシュー
リンクをコピー
Open
Open
proposal: crypto/fips140: do not bloat crypto code unnecessarily #81639
リンクをコピー
Labels
Proposal
Proposal-Crypto
Proposal related to crypto packages or other security issues
Proposal related to crypto packages or other security issues
Milestone
Proposal
Description
zx2c4
opened on Sep 21, 2026
Issue body
actions
Abstract
FIPS140コード、特にそのRNGは、ほとんどのGoバイナリで未使用かつ肥大化しています。最も特殊なユーザーを除き、実際にはこのほとんど役に立たない(技術的な観点から)コードを有効にするための手間をかけません。そのため、それは単にそこにあり、メモリを無駄にし(初期化関数は依然としてトリガーされます)、ディスク容量を無駄にし、キャッシュをいっぱいにし、かつてクリーンだった暗号ライブラリセットに非常に歓迎されない重みとなっています。この提案は、未使用のFIPSコードをコンパイルしないように、新しいデフォルト値GOFIPS140=disabledを追加することです。
Motivation
新しいfips140コードは多くの間接参照を追加し、無効になっているか使用されていない場合でも、結果のバイナリのコードサイズを著しく肥大化させます。その使用は、デフォルトで無効になっているGODEBUGフラグによってゲートされています。それでも、それは常にGoバイナリにコンパイルされます。そのフレームワークを通じて大量の暗号化を間接参照する(そしてそれがGODEBUGフラグで有効になっていない場合に早期に終了する)ことに加えて、それは大量の追加の暗号化と複雑さをインポートします。私の知る限り、そのフレームワークを通じた多くの間接参照を引き起こすことに加えて、それは以下に分岐の多いコードパスを追加します。
TLS
RSA/PKCS1
乱数生成器ラッパー関数
AES/GCM
これらのすべてのケースで追加の未使用コードを追加するのは残念だと思います。そして、これらすべては代わりにコンパイル時定数にゲートされるべきです(Enabledシンボルはvarからconstになる可能性があります)。しかし、私が特にひどいと思うのはRNGの状況です。そこで、私が何を意味するかを説明するために、それに焦点を当てます。
私は2つのテストプログラムを作成しました。
tester1: package main func main() { println("hello") }
tester2: package main import "crypto/rand" func main() { var b [1]byte rand.Read(b[:]) println("hello", b[0]) }
tester2がどのcryptoパッケージをプルインするか見てみましょう。当然、crypto/rand、そしてそれをさまざまなsyscallにディスパッチしたり、優れたランダムバイトを取得するために必要なその他のものにディスパッチするための内部cryptoロジックがプルインされると予想されます。実際にはそうではありません。
$ comm -13 <(go tool objdump tester1 | grep ^TEXT\ crypto | sort) <(go tool objdump tester2 | grep ^TEXT\ crypto | sort)
TEXT crypto/fips140.init(SB)
<autogenerated>
TEXT crypto.init(SB)
<autogenerated>
TEXT crypto/internal/entropy/v1%2e0%2e0.digestBytes(SB) /usr/lib/go/src/crypto/internal/entropy/v1.0.0/sha384.go
TEXT crypto/internal/entropy/v1%2e0%2e0.newSource(SB) /usr/lib/go/src/crypto/internal/entropy/v1.0.0/entropy.go
TEXT crypto/internal/entropy/v1%2e0%2e0.Samples(SB) /usr/lib/go/src/crypto/internal/entropy/v1.0.0/entropy.go
TEXT crypto/internal/entropy/v1%2e0%2e0.Seed(SB) /usr/lib/go/src/crypto/internal/entropy/v1.0.0/entropy.go
TEXT crypto/internal/entropy/v1%2e0%2e0.sha384Block(SB) /usr/lib/go/src/crypto/internal/entropy/v1.0.0/sha384.go
TEXT crypto/internal/entropy/v1%2e0%2e0.SHA384(SB) /usr/lib/go/src/crypto/internal/entropy/v1.0.0/sha384.go
TEXT crypto/internal/entropy/v1%2e0%2e0.(*source).Sample(SB) /usr/lib/go/src/crypto/internal/entropy/v1.0.0/entropy.go
TEXT crypto/internal/fips140/aes.(*Block).BlockSize(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes.go
TEXT crypto/internal/fips140/aes.(*CBCDecrypter).CryptBlocks(SB) /usr/lib/go/src/crypto/internal/fips140/aes/cbc.go
TEXT crypto/internal/fips140/aes.(*CBCEncrypter).CryptBlocks(SB) /usr/lib/go/src/crypto/internal/fips140/aes/cbc.go
TEXT crypto/internal/fips140/aes.cryptBlocksDecGeneric(SB) /usr/lib/go/src/crypto/internal/fips140/aes/cbc.go
TEXT crypto/internal/fips140/aes.cryptBlocksEncGeneric(SB) /usr/lib/go/src/crypto/internal/fips140/aes/cbc.go
TEXT crypto/internal/fips140/aes.ctrBlocks1Asm.abi0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_amd64.s
TEXT crypto/internal/fips140/aes.ctrBlocks1(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_asm.go
TEXT crypto/internal/fips140/aes.ctrBlocks2Asm.abi0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_amd64.s
TEXT crypto/internal/fips140/aes.ctrBlocks2(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_asm.go
TEXT crypto/internal/fips140/aes.ctrBlocks4Asm.abi0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_amd64.s
TEXT crypto/internal/fips140/aes.ctrBlocks4(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_asm.go
TEXT crypto/internal/fips140/aes.ctrBlocks8Asm.abi0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_amd64.s
TEXT crypto/internal/fips140/aes.ctrBlocks8(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr_asm.go
TEXT crypto/internal/fips140/aes.ctrBlocks(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr.go
TEXT crypto/internal/fips140/aes.(*CTR).XORKeyStreamAt(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr.go
TEXT crypto/internal/fips140/aes.(*CTR).XORKeyStream(SB) /usr/lib/go/src/crypto/internal/fips140/aes/ctr.go
TEXT crypto/internal/fips140/aes.decryptBlockAsm.abi0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_amd64.s
TEXT crypto/internal/fips140/aes.decryptBlockGeneric(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_generic.go
TEXT crypto/internal/fips140/aes.decryptBlock(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_asm.go
TEXT crypto/internal/fips140/aes.encryptBlockAsm.abi0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_amd64.s
TEXT crypto/internal/fips140/aes.encryptBlockGeneric(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_generic.go
TEXT crypto/internal/fips140/aes.encryptBlock(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_asm.go
TEXT crypto/internal/fips140/aes.expandKeyAsm.abi0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_amd64.s
TEXT crypto/internal/fips140/aes.expandKeyGeneric(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_generic.go
TEXT crypto/internal/fips140/aes/gcm.(*CMAC).deriveSubkeys(SB) /usr/lib/go/src/crypto/internal/fips140/aes/gcm/cmac.go
TEXT crypto/internal/fips140/aes/gcm.(*CMAC).MAC(SB) /usr/lib/go/src/crypto/internal/fips140/aes/gcm/cmac.go
TEXT crypto/internal/fips140/aes/gcm.(*CounterKDF).DeriveKey(SB) /usr/lib/go/src/crypto/internal/fips140/aes/gcm/ctrkdf.go
TEXT crypto/internal/fips140/aes/gcm.init.0.func1(SB) /usr/lib/go/src/crypto/internal/fips140/aes/gcm/cast.go
TEXT crypto/internal/fips140/aes/gcm.init.0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/gcm/cast.go
TEXT crypto/internal/fips140/aes/gcm.init.1(SB) /usr/lib/go/src/crypto/internal/fips140/aes/gcm/gcm_asm.go
TEXT crypto/internal/fips140/aes/gcm.init(SB)
<autogenerated>
TEXT crypto/internal/fips140/aes.init.0(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_asm.go
TEXT crypto/internal/fips140/aes.init.1.func1(SB) /usr/lib/go/src/crypto/internal/fips140/aes/cast.go
TEXT crypto/internal/fips140/aes.init.1(SB) /usr/lib/go/src/crypto/internal/fips140/aes/cast.go
TEXT crypto/internal/fips140/aes.init(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_asm.go
TEXT crypto/internal/fips140/aes.(*KeySizeError).Error(SB)
<autogenerated>
TEXT crypto/internal/fips140/aes.KeySizeError.Error(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes.go
TEXT crypto/internal/fips140/aes.newBlock(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes_asm.go
TEXT crypto/internal/fips140/aes.newOutlined(SB) /usr/lib/go/src/crypto/internal/fips140/aes/aes.go
TEXT crypto/internal/fips140.CAST(SB) /usr/lib/go/src/crypto/internal/fips140/cast.go
TEXT crypto/internal/fips140/check.init.0(SB) /usr/lib/go/src/crypto/internal/fips140/check/check.go
TEXT crypto/internal/fips140deps/cpu.init(SB) /usr/lib/go/src/crypto/internal/fips140deps/cpu/cpu.go
TEXT crypto/internal/fips140deps/time.monoTime(SB) /usr/lib/go/src/runtime/time.go
TEXT crypto/in