TL;DR
- Go의 FIPS 140 코드가 기본적으로 대부분의 바이너리에 포함되는 문제를 해결하기 위해, 기본
GOFIPS140값을disabled로 설정하고 미사용 FIPS 코드의 컴파일을 막자는 제안임. - FIPS 140 코드는 기본적으로 비활성화되어도 바이너리에 포함되며, 초기화 함수 실행과 코드 크기 증가, 메모리·디스크·캐시 낭비를 유발한다는 주장임.
crypto/rand만 사용하는 간단한 프로그램에도 엔트로피 수집기, AES, DRBG, HMAC, SHA-256·SHA-3·SHA-512 등 광범위한 FIPS 구현이 포함되는 사례임.fips140.Enabled를 변수에서 컴파일 타임 상수로 바꾸고, 일부 파일에fips140빌드 태그를 적용해 미사용 코드와 복잡한 의존성을 제거하자는 제안임.- 새 기본값은 FIPS 전용 경로를 컴파일에서 제외하며,
off,latest,certified,inprocess, 특정 버전 값의 동작은 기존과 동일하게 유지하는 변경임.
개요
- FIPS 140 코드, 특히 난수 생성기(RNG)는 대다수 Go 바이너리에서 사용되지 않으면서 코드 크기를 불필요하게 늘린다는 주장임.
- 기술적 관점에서 거의 쓸모없는 코드임에도 이를 실제로 사용하는 일부 사용자를 제외한 대부분은 활성화 절차를 거치지 않으며, 코드는 메모리와 디스크 공간을 차지하고 캐시를 채움.
- 제안의 핵심은 기본
GOFIPS140=disabled값을 추가해 사용하지 않는 FIPS 코드를 컴파일하지 않는 것임.
동기
- 새 FIPS 140 코드는 간접 호출을 늘리고 최종 바이너리의 크기를 크게 키우며, 비활성 상태이거나 사용하지 않는 경우에도 컴파일됨.
- 사용 여부는 기본적으로 꺼져 있는
GODEBUG플래그로 제어되지만, 관련 코드는 Go 바이너리에 항상 포함됨. - 암호화 코드의 상당 부분을 FIPS 프레임워크로 우회한 뒤
GODEBUG플래그가 켜지지 않았으면 조기에 빠져나오며, 추가 암호화 코드와 복잡성도 가져옴. - 프레임워크를 거치는 간접 호출 외에도 다음 경로에 분기 처리가 추가된다는 주장임.
- TLS
- RSA/PKCS1
- 난수 생성기 래퍼 함수
- AES/GCM
- 이러한 미사용 코드는 컴파일 타임 상수로 제어해야 하며,
Enabled심볼도 변수에서 상수로 바꿀 수 있다는 제안임. - 특히 난수 생성기 사례를 통해 불필요한 코드 증가를 설명함.
crypto/rand를 가져와 1바이트를 읽는 프로그램과 암호화 패키지를 전혀 가져오지 않는 프로그램을 비교하고,go tool objdump출력의 차이를 확인함.crypto/rand를 사용하면 시스템 호출 등 안전한 난수 바이트 획득에 필요한 일부 내부 암호화 코드가 추가될 것으로 예상할 수 있지만, 실제로는 다음 구성 요소가 포함됨.- 사용자 공간 엔트로피 수집기와 해당 수집기를 위한 SHA-384 구현
- AES 및 AES-NI 가속 AES 구현
- AES용 CTR 및 GCM 구현
- 일부 CPU 감지 코드
- FIPS 지정 DRBG 알고리즘 구현
- HMAC 구현
- SHA-256 및 AVX2 가속 SHA-256 구현
- cSHAKE를 포함한 SHA-3 및 AVX2 가속 SHA-3 구현
- SHA-512 구현
- 일반 XOR 바이트 처리 루틴
crypto/internal/sysrand와crypto/rand의 실제 시스템 호출 래퍼- 이 구성은 지나치게 방대하며, FIPS 난수 생성 기능이 필요한 사용자가 있더라도 별도 영역에 격리하고 모든
crypto/rand사용 바이너리에 기본 포함하지 않아야 한다는 주장임.
고려 사항
- 현재 관련 코드는
GODEBUG로 제어되는fips140.Enabled멤버에 따라 동작함. fips140.Enabled를 변수에서 상수로 바꾸면 컴파일러가 미사용 코드를 일반적인 최적화 과정에서 제거할 수 있다는 제안임.- 복잡한 의존성 연결 일부는 특정 파일에
fips140빌드 태그를 적용해 해결할 수 있으며, 이 경우에도 호출은 FIPS 중계 함수를 거치지만 알고리즘과 불필요한 코드는 제거되고 중계 함수 대부분도 인라인 처리될 수 있음. - FiloSottile과 비공식적으로 논의하는 과정에서 테스트와 지속적 통합(CI)에 대한 우려가 제기됨.
- 이에 따라 필요한 부분을 다시 컴파일하도록 테스트를 재구성해야 하며, 현재 변경 목록(CL) 묶음은 이를 유지 관리 부담을 줄이는 방식으로 자동화함.
제안
- 새 기본
GOFIPS140=disabled값은 난수 생성기와 추가 분기 등 FIPS 전용 경로를 바이너리에 컴파일하지 않는 동작임. GOFIPS140값별 변경 전후 동작은 다음과 같음.- 값 미설정: 변경 전 기본값은
off, 변경 후 기본값은disabled disabled: 변경 전에는 유효하지 않은 값, 변경 후에는 FIPS 모드를 사용할 수 없고fips140.Enabled가 컴파일 타임 상수false임off: FIPS 지원 코드를 포함하되 시작 시 비활성화하는 동작으로 변경 없음latest: 현재 모듈을 사용하고 기본 활성화하는 동작으로 변경 없음certified: 인증된 스냅샷을 사용하고 기본 활성화하는 동작으로 변경 없음inprocess: 인증 절차 진행 중인 스냅샷을 사용하고 기본 활성화하는 동작으로 변경 없음- 지원 버전 지정: 지정된 스냅샷을 사용하고 기본 활성화하는 동작으로 변경 없음
구현
- 변경을 구현하고 테스트 자동화를 통해 향후 유지 관리 부담을 줄이는 변경 목록(CL)이 준비되어 있음: https://go-review.googlesource.com/c/go/+/836445 및 이후 변경 목록임.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요