본문 바로가기

프로그래밍

AES 암호화, 그리고 AES-NI, 손에 잡힐듯 말듯한 보물.

AES (Advanced Encryption Standard)는 현재 널리 사용되고 있는 표준 암호화 알고리즘의 통칭이다. 암호화 알고리즘은 수차례의 진화를 거듭해 왔으며, 암호화에 있어서만은 독자노선을 가지던 많은 회사들도 결국에는 현재는 AES에 많이 의존하고 있다. 현재 내가 참여하고 있는 시스템도 AES를 이용하여 비디오를 암호화 하고 있다.


AES가 작은 데이터 뿐만 아니라 비디오와 같은 대용량 데이터의 암호화에 사용되면서, 성능의 중요성이 대두되었고, 2008년에는 인텔에서 AES 연산을 코어 레벨에서 수행하기 위한 instruction set을 제안하였다. 이는 실제로 엄청난 성능향상을 가져오는데, 소프트웨어 레벨의 연산보다 8배정도 빠른 암호화를 제공한다. 이는 AES-NI (AES New Instructions)라고 불리우며 일부 AMD 및 Intel이 지원하고 있다.


암호화를 수행하는 서버는 무엇보다 성능이 중요하기에, C++로 개발되는 경우가 많다. 따라서 C++의 대표적인 암호화 라이브러리인 Cryptopp는 거의 대체 불가능한 수준까지 확산 되었는데, 이 라이브러리의 장점중 하나는, AES-NI를 지원한다는 것이다.


단, AES-NI의 시스템 및 운영체제 제한이 걸림돌이 되고있기는 하다. 수많은 customer들이 아직도 엄청나게 오래된 RHEL5를 사용하고 있는데, AES-NI는 단순히 이야기하자면 RHEL6 이상에서 지원된다. 컴파일러 제약또한 존재하는데, 오래된 G++는 AES-NI를 지원하지 않는다. 따라서 명확히 좋은것임에도 불구하고 사용하지 못하고 있는 케이스가 많다. 우리 시스템도 역시 같은 이유로 AES-NI를 사용하지 못하고 있다. 추후 RHEL6이상이 기본사양으로 결정되고, 중앙 빌드 서버의 컴파일러 버전이 상향 조정되면, 그때 AES-NI를 도입함으로써 상당한 성능 향상을 기대할 수 있을것이다


Cryptopp는 시스템의 AES-NI의 지원 여부를 검사하는 로직이 있어, 지원하는 경우에만 시스템콜을 호출한다. 그런데 아직도 cryptopp의 AES-NI auto detection에 버그가 있어서, 어떤 시스템에서는 바로 crash를 발생시키기도 한다. 즉 요구되는 시스템 사양이나 종류가 아주 정확히 매칭 되지 않으면 간단히 적용하기 어렵다는 이야기다. 이 문제는 다수의 vendor들에게 서버를 제공해야하는 상황에서 상당한 골칫거리다.


이에 대한 한가지 대책은, cryptopp를 AES-NI를 강제로 막은 버젼과 AES-NI를 허용한 버젼 두가지로 컴파일 한 후, 실행 전에 시스템이 AES NI를 지원하는지, 그리고 정확히 구동중인지 검사하고 그에 맞는 shared object가 로딩되도록 하는것이다.


그럼, 시스템의 AES-NI의 지원여부를체크하려면 어떻게 해야 할까.


1. CPU가 AES-NI를 지원하는지 확인한다. 숫자가 0이 아니면 지원하는것이다.

$ cat /proc/cpuinfo | grep aes | wc -l


2. aesni_intel 커널 모듈이 로딩 되었는지 확인한다

$ grep module /proc/crypto | sort -u

module       : aesni_intel

module       : aes_x86_64

module       : arc4

module       : kernel


3. aesni_intel 커널 모듈을 로딩한다

$ /sbin/modinfo aesni_intel

filename:       /lib/modules/3.0.0-13-generic/kernel/arch/x86/crypto/aesni-intel.ko

alias:          aes

license:        GPL

description:    Rijndael (AES) Cipher Algorithm, Intel AES-NI instructions optimized

srcversion:     61A51F44F192D7CE0FBA795

depends:        cryptd,aes-x86_64

vermagic:       3.0.0-13-generic SMP mod_unload modversions 


현재 cryptopp에서 AES-NI auto detection을 수정하려는 계획이 있는것으로 알고있으나, 그 시점이 언제가 될 지는 명확하지가 않다. 따라서 불특정 시스템으로 AES-NI를 사용하는 소프트웨어를 배포해야 하는 경우가 있다면 위의 방법을 응용해 보기 바란다.

  • double 2015.04.20 12:27 댓글주소 수정/삭제 댓글쓰기

    안녕하세요.
    이번 포스팅 내용과는 관계가 없는 질문인데,
    위에 Crypto++ 라이브러리 내용이 언급이 되어서 질문 드립니다.
    제가 지금 crypto++라이브러리를 이용하여 암호화 프로그래밍을 하려고 하는데, crypto++라이브러리를 사용하여 vs환경에서 c언어로 aes나 sha를 동작시킬 수 있는지 궁금합니다.
    c로 암호화 프로그래밍을 하기 위해서 openssl을 사용할 수도 있지만, crypto++라이브러리가 더 다양한 암호라이브러리를 지원해서 이것으로 사용하려고 합니다.

    감사합니다.

  • crypto++ 를 C에서 사용하려면 사용하고자 하는 기능을 c function으로 래핑하여 링크하는 방법 밖에는 없을 것 같습니다만 권장되는 방법이 아니구요, 그 외에는 딱히 직접 사용할 방법도 없고, 추천하지도 않습니다. 말씀하신대로 openssl을 사용하시는게 좋을듯 하네요..

    • double 2015.04.22 02:44 댓글주소 수정/삭제

      딱히 특별한 방법이 있는 건 아니군요,,
      많은 도움이 되었습니다.
      답변 감사합니다.