10 Security
i.MX 플랫폼은 일련의 보안 가속 하위 시스템을 정의한다.
10.1 CAAM kernel driver
10.1.1 Introduction
Linux 커널에는 NXP CAAM 보안 하드웨어 블럭용 Scatterlist Crypto API 드라이버가 포함되어 있다. 모든 디스크 암호화와 키 관리 제품군이 하드웨어를 자동으로 사용하여 암호화 가속을 수행하는 방식으로 DM-Crypt, Keyctl과 같은 커널 내 암호화 사용자와 원활하게 통합된다. CAAM 하드웨어는 Linux 커널에서 내부 블럭 이름인 Cryptographic Accelerator and Assurance Module을 따서 'caam'으로 알려져 있다.
엔진과 통신(예: 요청 제출)하는 데 사용할 수 있는 몇 가지 HW 인터페이스("backends")가 있으며, 사용 가능 여부는 SoC에 따라 다르다:
- Register Interface (RI) - 모든 SoC에서 사용 가능(DPAA2 SoC에서는 커널 액세스가 제한됨).
주요 목적은 디버깅(예: 디스크립터를 통한 단계별 실행)이지만, RNG 초기화에는 사용된다. - Job Ring Interface (JRI) - 레거시 인터페이스는 모든 SoC에서 사용할 수 있으며, 대부분의 SoC에는 4개의 링이 있다.
참고:
예를 들어 Trusted Firmware-A (TF-A)와 같은 펌웨어가 링 중 하나를 예약하는 경우와 같이 커널에서 액세스 가능하거나 표시되는 링의 수가 적은 경우가 있다.
이러한 백엔드 위에 "frontends"가 있는데, 이는 Linux Crypto API와 백엔드 드라이버 사이에 있는 드라이버이다. 이들의 주요 임무는 다음과 같다:
- 지원된는 암호화 알고리즘 등록.
- Linux Crypto API를 통해 사용자의 암호화 요청을 처리하고, 사용 중인 백엔드에서 이해할 수 있는 적절한 형식으로 변환한다.
- 사용 중인 백엔드의 CAAM 엔진 응답을 사용자에게 전달한다.
특정 구현을 사용하려면, 일반적인 "algorithm name" 대신 특정(고유) "driver name"을 사용하여 명시적으로 요청할 수 있다. 공식 Linux Kernel Crypto API 문서(Crypto API Cipher References And Priority 섹션)를 참조한다. 현재, JRI 프론트엔드의 기본 우선 순위는 3000이다.
10.1.2 Source files
드라이버 소스 코드는 Linux 커널 소스 트리의 drivers/crypto/caam에서 유지 관리된다. 다음은 CAAM에 매핑되는 일부 파일 목록이다. 일부 파일은 드라이버 로직이나 디자인에 의해서만 존재가 정당화되므로 생략되었다.
Table 67. Source files
Source File | Description | Module name |
---|---|---|
ctrl.[c,h] | Init (전역 설정, RNG, 전원 관리 등) | caam |
desc.h | HW 디스크립터 (CCSR 레지스터 등) | N/A |
desc_constr.h | 인라인 추가 - 디스크입터 생성 라이브러리 | N/A |
caamalg_desc.[c,h] | (공유된) 디스크립터 라이브러리 (대칭 암호화, AEAD) | caamalg_desc |
caamhash_desc.[c,h] | (공유된) 디스크립터 라이브러리 (HASH) | caamhash_desc |
caamrng.c | RNG (런타임) | N/A |
caamkeyblob_desc.[c,h] | 디스크립터 라이브러리 (black keys and blobs) | caamkeyblob_desc |
jr.[c,h] | JRI 백엔드 | caam_jr |
caamalg.c | JRI 프런트엔드 (대칭 암호화, AEAD) | N/A |
caamhash.c | JRI 프런트엔드 (hashing) | N/A |
caampkc.c, pkc_desc.c |
JRI 프런트엔드 (public key cryptography) | N/A |
caamkeyblob.[c,h] | JRI 프런트엔드 (black keys and blobs) | N/A |
caamkeygen.c | key와 blob 생성/임포트를 위한 IOCTL 호 | N/A |
10.1.3 Module loading
CAAM 백엔드 드라이버는 빌트인이나 모듈로 컴파일할 수 있다. 프런트엔드 드라이버는 백엔드 드라이버에 연결된다. 모듈 이름의 목록은 Section 10.1.2를 참조하고, 커널 구성이 어떻게 보이는지와 메뉴 항목과 모듈 및/또는 활성화된 기능 사이의 매핑에 대해서는 Section 10.1.4를 참조한다.
10.1.4 Kernel configuration
지정된 드라이버는 대상 플랫폼에 대해 기본적으로 커널에 구성되어 있어야 한다. 확실하지 않은 경우, 커널 구성의 Cryptographic API -> Hardware crypto devices 서브 메뉴에 있는 CONFIG_CRYPTO_DEV_FSL_CAAM을 확인한다.
Table 68. Kernel configuration tree view
Kernel configuration tree view option | Description |
---|---|
---Cryptographic API ---> [*] Hardware crypto devices ---> <*>CAAM/SNVS Security Violation Handler (EXPERIMENTAL) <*>Freescale CAAM-Multicore platform driver backend [ ] Enable debug output in CAAM driver <*> Freescale CAAM Job Ring driver backend ---> (9) Job Ring size [ ] Job Ring interrupt coalescing [*] Register algorithm implementations with the Crypto API [*] Register hash algorithm implementations with Crypto API [*] Register public key cryptography implementations with Crypto API [*] Register caam device for hwrng API [*] Register tagged key cryptography implementations with Crypto API [ ] Test caam rng [*] CAAM Secure Memory / Keystore API (EXPERIMENTAL) (7) Size of each keystore slot in Secure Memory <M> CAAM Secure Memory - Keystore Test/Example (EXPERIMENTAL) <M> Freescale Job Ring UIO support |
CAAM 디바이스 드라이버 활성화:
|
Table 69. Device tree binding
Property | Type | Status | Description |
---|---|---|---|
compatible | String | Required | fsl, sec-vX.Y (preferred) or fsl, secX.Y |
Sample Device Tree crypto node (샘플 디바이스 트리 암호화 노드)
crypto@30000 {
compatible = "fsl,sec-v4.0";
fsl,sec-era = <2>;
#address-cells = <1>;
#size-cells = <1>;
reg = <0x300000 0x10000>;
ranges = <0 0x300000 0x10000>;
interrupt-parent = <&mpic>;
interrupts = <92 2>;
clocks = <&clks IMX6QDL_CLK_CAAM_MEM>,
<&clks IMX6QDL_CLK_CAAM_ACLK>,
<&clks IMX6QDL_CLK_CAAM_IPG>,
<&clks IMX6QDL_CLK_EIM_SLOW>;
clock-names = "mem", "aclk", "ipg", "emi_slow";
};
10.1.5 How to test the drivers
암호화 드라이버는 부팅 시와 요청 시, 두 가지 모드로 유효성을 검사할 수 있다. 암호화 테스트 기능을 사용하려면, 다음과 같이 커널을 업데이트해야 한다.
Table 70. Kernel configuration
Kernel configuration | Description |
---|---|
--- Cryptographic API ---> [ ] Disable run-time self tests [ ] Enable extra run-time crypto self tests <M> Testing module |
암호화 드라이버 유효성 검사를 우회하는 기능을 선택 해제한다. 기본적으로, Linux 커널은 암호화 드라이버 유효성 검사를 우회한다. 알고리즘 등록 시, 일반적으로 수행되는 런타임 자 테스트를 비활성화한다. 무작위 퍼즈 테스트를 포함하여 등록된 암호화 알고리즘에 대한 추가 런타임 자체 테스트를 사용하도록 설정한다. 이러한 테스트는 일반 자체 테스트보다 실행하는 데 훨씬 오래 걸리므로 개발자 전용으로 사용해야 한다. 테스트 모듈을 활성화한다. |
부트 로그에서 암호화 테스트가 수행된 위치를 지정하는 섹션이다(부트 테스트가 성공적으로 통과하면, 아무런 정보도 보고 되지 않는다. 사용 가능한 테스트가 없는 알고리즘의 경우 dmesg에 라인이 출력된다):
[ 4.647985] alg: No test for
authenc(hmac(sha224),ecb(cipher_null)) (authenc-hmac-sha224-ecb-cipher_null-caam)
[ 4.661181] alg: No test for
authenc(hmac(sha256),ecb(cipher_null)) (authenc-hmac-sha256-ecb-cipher_null-caam)
[ 4.671345] alg: No test for
authenc(hmac(sha384),ecb(cipher_null)) (authenc-hmac-sha384-ecb-cipher_null-caam)
[ 4.681486] alg: No test for
authenc(hmac(sha512),ecb(cipher_null)) (authenc-hmac-sha512-ecb-cipher_null-caam)
[ 4.691608] alg: No test for authenc(hmac(md5),cbc(aes)) (authenc-hmac-md5-cbc-aes-caam)
[ 4.699802] alg: No test for
echainiv(authenc(hmac(md5),cbc(aes))) (echainiv-authenc-hmacmd5-cbc-aes-caam)
[ 4.710445] alg: No test for
echainiv(authenc(hmac(sha1),cbc(aes))) (echainiv-authenc-hmacsha1-cbc-aes-caam)
[ 4.720488] alg: No test for authenc(hmac(sha224),cbc(aes)) (authenc-hmac-sha224-cbc-aes-caam)
[ 4.734647] alg: No test for
echainiv(authenc(hmac(sha224),cbc(aes))) (echainiv-authenchmac-sha224-cbc-aes-caam)
[ 4.750504] alg: No test for
echainiv(authenc(hmac(sha256),cbc(aes))) (echainiv-authenchmac-sha256-cbc-aes-caam)
[ 4.762468] alg: No test for authenc(hmac(sha384),cbc(aes)) (authenc-hmac-sha384-cbc-aes-caam)
[ 4.771188] alg: No test for
echainiv(authenc(hmac(sha384),cbc(aes))) (echainiv-authenchmac-sha384-cbc-aes-caam)
[ 4.782380] alg: No test for
echainiv(authenc(hmac(sha512),cbc(aes))) (echainiv-authenchmac-sha512-cbc-aes-caam)
[ 4.792765] alg: No test for
authenc(hmac(md5),cbc(des3_ede)) (authenc-hmac-md5-cbcdes3_ede-caam)
[ 4.801832] alg: No test for
echainiv(authenc(hmac(md5),cbc(des3_ede))) (echainiv-authenchmac-md5-cbc-des3_ede-caam)
[ 4.812814] alg: No test for
echainiv(authenc(hmac(sha1),cbc(des3_ede))) (echainiv-authenchmac-sha1-cbc-des3_ede-caam)
[ 4.823942] alg: No test for
echainiv(authenc(hmac(sha224),cbc(des3_ede))) (echainivauthenc-hmac-sha224-cbc-des3_ede-caam)
[ 4.835465] alg: No test for
echainiv(authenc(hmac(sha256),cbc(des3_ede))) (echainivauthenc-hmac-sha256-cbc-des3_ede-caam)
[ 4.846980] alg: No test for
echainiv(authenc(hmac(sha384),cbc(des3_ede))) (echainivauthenc-hmac-sha384-cbc-des3_ede-caam)
[ 4.858497] alg: No test for
echainiv(authenc(hmac(sha512),cbc(des3_ede))) (echainivauthenc-hmac-sha512-cbc-des3_ede-caam)
[ 4.869764] alg: No test for authenc(hmac(md5),cbc(des)) (authenc-hmac-md5-cbc-des-caam)
[ 4.877977] alg: No test for
echainiv(authenc(hmac(md5),cbc(des))) (echainiv-authenc-hmacmd5-cbc-des-caam)
[ 4.888078] alg: No test for
echainiv(authenc(hmac(sha1),cbc(des))) (echainiv-authenc-hmacsha1-cbc-des-caam)
[ 4.898356] alg: No test for
echainiv(authenc(hmac(sha224),cbc(des))) (echainiv-authenchmac-sha224-cbc-des-caam)
[ 4.908994] alg: No test for
echainiv(authenc(hmac(sha256),cbc(des))) (echainiv-authenchmac-sha256-cbc-des-caam)
[ 4.919653] alg: No test for
echainiv(authenc(hmac(sha384),cbc(des))) (echainiv-authenchmac-sha384-cbc-des-caam)
[ 4.930292] alg: No test for
echainiv(authenc(hmac(sha512),cbc(des))) (echainiv-authenchmac-sha512-cbc-des-caam)
[ 4.940688] alg: No test for
authenc(hmac(md5),rfc3686(ctr(aes))) (authenc-hmac-md5-rfc3686-ctr-aes-caam)
[ 4.950372] alg: No test for
seqiv(authenc(hmac(md5),rfc3686(ctr(aes)))) (seqiv-authenchmac-md5-rfc3686-ctr-aes-caam)
[ 4.961281] alg: No test for
seqiv(authenc(hmac(sha1),rfc3686(ctr(aes)))) (seqiv-authenchmac-sha1-rfc3686-ctr-aes-caam)
[ 4.972281] alg: No test for
authenc(hmac(sha224),rfc3686(ctr(aes))) (authenc-hmac-sha224-rfc3686-ctr-aes-caam)
[ 4.982482] alg: No test for
seqiv(authenc(hmac(sha224),rfc3686(ctr(aes)))) (seqiv-authenchmac-sha224-rfc3686-ctr-aes-caam)
[ 4.993903] alg: No test for
seqiv(authenc(hmac(sha256),rfc3686(ctr(aes)))) (seqiv-authenchmac-sha256-rfc3686-ctr-aes-caam)
[ 5.005331] alg: No test for
seqiv(authenc(hmac(sha384),rfc3686(ctr(aes)))) (seqiv-authenchmac-sha384-rfc3686-ctr-aes-caam)
[ 5.016763] alg: No test for
seqiv(authenc(hmac(sha512),rfc3686(ctr(aes)))) (seqiv-authenchmac-sha512-rfc3686-ctr-aes-caam)
[ 5.028023] caam algorithms registered in /proc/crypto
[ 5.157622] caam_jr 31430000.jr2: registering rng-caam
[ 5.206167] caam 31400000.caam: caam pkc algorithms
registered in /proc/crypto
10.2 Crypto algorithms support
- Linux 커널 Scatterlist Crypto API에서 지원되는 알고리즘
Linux 커널에는 NETKEY 스택이라고도 하는 IPsec 구현을 포함하여 Scatterlist Crypto API의 다양한 사용자를 포함한다. 따라서 드라이버는 지원되는 알고리즘을 Crypto API에 등록한 후, 패킷별 대칭 암호화 요청을 처리하고 이를 CAAM 하드웨어로 전달하는 데 사용된다. CAAM 하드웨어는 요청을 비동기적으로 처리하기 때문에, 드라이버는 암호화 API에 비동기 알고리즘 구현을 등록한다(ahash, skcipher 그리고 .cra_flags에 CRYPTO_ALG_ASYNC가 설정된 헤드). 하드웨어와 드라이버 소프트웨어 버전의 조합에 따라 서로 다른 알고리즘을 지원하므로, 원하는 대상 시스템의 /proc/crypto에서 드라이버 이름을 검색하면 어떤 알고리즘이 지원되는지 정확하게 알 수 있다. - Authenticated Encryption with Associated Data(AEAD) 알고리즘
이러한 알고리즘은 IPsec와 TLS 프로토콜의 경우와 같이 암호화할 데이터가 인증할 데이터와 겹치거나 부분적으로 겹치는 애플리케이션에서 사용된다. 이러한 알고리즘은 하드웨어에 입력 데이터를 한 번 통과하면, 암호화와 인증 데이터가 동시에 기록되도록 드라이버에서 구현된다. AEAD 알고리즘은 주로 IPsec ESP와 함께 사용하기 위한 것이다(단, TLS(1.x) 레코드 레이어 암호화(KTLS 지원)도 지원된다). CAAM 드라이버는 현재 다음과 같은 AEAD 알고리즘 오프로드를 지원한다:
- "stitched" AEAD: { NULL, CBC-AES, CBC-DES, CBC-3DES-EDE, RFC3686-CTR-AES } x HMAC-{MD-5, SHA-1,-224,-256,-384,-512}의 모든 조합
- "true" AEAD: 일반 GCM-AES, IPsec에서 사용되는 GCM-AES: RFC4543-GCM-AES 그리고 RFC4106-GCM-AES
- Encryption 알고리즘
- Authentication 알고리즘
CAAM 드라이버의 ahsah 지원에는 키가 있는 (hmac) 해싱 알고리즘과 키가 없는 해싱 알고리즘이 포함된다. - Asymmetric(public key) 알고리즘
현재, CAAM 드라이버는 pkcs1pad(rsa-caam, sha256) 드라이버와 함께 RSA-Encrypt와 RSA-Decrypt를 지원한다. - CAAM 드라이버가 지원하는 알고리즘
root@imx8mqevk:~# cat /proc/crypto | grep caam
driver : pkcs1pad(rsa-caam,sha256)
driver : rsa-caam
driver : cmacaes-caam
driver : xcbc-aes-caam
driver : md5-caam
driver : hmac-md5-caam
driver : sha256-caam
driver : hmac-sha256-caam
driver : sha224-caam
driver : hmac-sha224-caam
driver : sha1-caam
driver : hmac-sha1-caam
driver : seqiv-authenchmac-sha256-rfc3686-ctr-aes-caam
driver : authenc-hmac-sha256-rfc3686-ctr-aes-caam
driver : seqiv-authenc-hmac-sha224-rfc3686-ctr-aes-caam
driver : authenc-hmac-sha224-rfc3686-ctr-aes-caam
driver : seqiv-authenc-hmac-sha1-rfc3686-ctr-aes-caam
driver : authenc-hmac-sha1-rfc3686-ctr-aes-caam
driver : seqiv-authenc-hmac-md5-rfc3686-ctr-aes-caam
driver : authenchmac-md5-rfc3686-ctr-aes-caam
driver : echainiv-authenchmac-sha256-cbc-des-caam
driver : authenc-hmac-sha256-cbcdes-caam
driver : echainiv-authenc-hmac-sha224-cbc-des-caam
driver : authenc-hmac-sha224-cbc-des-caam
driver : echainivauthenc-hmac-sha1-cbc-des-caam
driver : authenc-hmac-sha1-cbc-des-caam
driver : echainiv-authenc-hmac-md5-cbc-des-caam
driver : authenc-hmac-md5-cbc-des-caam
driver : echainivauthenc-hmac-sha256-cbc-des3_ede-caam
driver : authenchmac-sha256-cbc-des3_ede-caam
driver : echainiv-authenchmac-sha224-cbc-des3_ede-caam
driver : authenc-hmac-sha224-cbc-des3_ede-caam
driver : echainiv-authenc-hmac-sha1-cbcdes3_ede-caam
driver : authenc-hmac-sha1-cbc-des3_ede-caam
driver : echainiv-authenc-hmac-md5-cbc-des3_ede-caam
driver : authenc-hmac-md5-cbc-des3_ede-caam
driver : echainiv-authenchmac-sha256-cbc-aes-caam
driver : authenc-hmac-sha256-cbcaes-caam
driver : echainiv-authenc-hmac-sha224-cbc-aes-caam
driver : authenc-hmac-sha224-cbc-aes-caam
driver : echainivauthenc-hmac-sha1-cbc-aes-caam
driver : authenc-hmac-sha1-cbc-aes-caam
driver : echainiv-authenc-hmac-md5-cbc-aes-caam
driver : authenc-hmac-md5-cbc-aes-caam
driver : authenc-hmacsha256-ecb-cipher_null-caam
driver : authenc-hmac-sha224-ecbcipher_null-caam
driver : authenc-hmac-sha1-ecb-cipher_nullcaam
driver : authenc-hmac-md5-ecb-cipher_null-caam
driver : gcm-aes-caam
driver : rfc4543-gcm-aes-caam
driver : rfc4106-gcm-aes-caam
driver : ecb-arc4-caam
driver : ecb-des3-caam
driver : tk-ecb-aes-caam
driver : ecb-aes-caam
driver : ecbdes-caam
driver : rfc3686-ctr-aes-caam
driver : ctr-aes-caam
driver : cbc-des-caam
driver : cbc-3des-caam
driver : tk-cbcaes-caam
driver : cbc-aes-caam
root@imx8mqevk:~#
10.3 CAAM Job Ring backend driver specifications
CAAM Job Ring 백엔드 드라이버(caam_jr)는 프런트엔드 드라이버(caamalg, caamhash, caampkc, caamrng, caamkeyblob)의 암호화 API 서비스 요청을 CAAM 엔진으로 제출하기 위해 작업 링 인터페이스(JRI)를 구현하고 사용한다.
CAAM 드라이버에는 특히 하드웨어 작업 링 크기와 인터럽트 병합과 같은 몇 가지 옵션이 있다. 특정 사용 사례에 맞게 성능을 미세 조정하는 데 사용할 수 있다.
Freescale CAAM Job Ring 드라이버 백엔드 옵션은 작업 링 백엔드(caam_jr)를 활성화한다. Job Ring Size 서브 옵션은 사용자가 하드웨어 작업 링의 크기를 선택할 수 있도록 한다. 요청이 버스트 형태로 드라이버 대기열 진입점에 도착하는 경우, 버스트의 최대 길이를 추정할 수 있다. 사용자는 최대 버스트 길이를 설정하여 성능과 메모리 소비를 절약할 수 있다.
Job Ring 인터럽트 병합 서브 옵션을 사용하면 하드웨어의 인터럽트 병합 기능 사용을 선택할 수 있다. 드라이버는 이미 소프트웨어로 IRQ 병합을 수행하며, 실제로 무손실(zero-loss) 벤치마크에서는 이 옵션을 해제했을 때 더 나은 결과가 나타났다. 이 옵션을 선택하면 두 가지 추가 옵션이 적용된다:
- Job Ring interrupt coalescing count threshold (CRYPTO_DEV_FSL_CAAM_INTC_THLD) Device Drivers
디스크립터 완료 임계치의 값을 1~256 범위에서 선택한다. 1을 선택하면 병합 기능이 효과적으로 무효화되며, 선택한 링 크기보다 크거나 같으면 각 인터럽트에 대해 시간 제한이 강제로 적용된다. - Job Ring interrupt coalescing timer threshold (CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD)
64 CAAM 인터페이스 클럭의 배수로 완료 제한 시간 임계값을 선택한다. 이 기간(window) 내에 새로운 디스크립터 완료가 발생하지 않는 경우 (그리고 최소한 완료된 작업이 하나 이상 보류중인 경우) 인터럽트가 발생한다. 이 값은 1~65535 범위에서 선택할 수 있다.
Crypto API, hwrng API에 각각 등록하는 옵션을 사용하면, 프런트엔드 드라이버는 알고리즘 기능을 해당 API에 등록할 수 있다. 목적이 CAAM 엔진에서 오프로드하는 대신 소프트웨어(GPP)에서 Crypto API 요청을 수행하는 경우에만 선택을 해제해야 한다.
애플리케이션의 특성상 소규모 요청이 많아 소프트웨어(코어) 암호화 대기 시간을 선호할 수 있으므로, caamhash 프런트엔드(해시 알고리즘)는 개별적으로 해제될 수 있다.
필요한 경우, caampkc 프런트엔드(공개 키/비대칭 알고리즘)도 해제될 수 있다.
커널에서 사용할 수 있는 대체 엔트로피 소스가 있는 경우, caamrng 프런트엔드(Random Number Generation)를 해제될 수 있다.
caamkeyblob 프런트엔드(태그가 지정된 키를 지원하는 알고리즘)는 태그가 지정된 키나 Blob를 사용하지 않으면 해제될 수 있다.
10.3.1 Verifying driver operation and correctness
암호화 오프로드로 인한 성능 이점 외에도 dmesg에서 드라이버 메세지를 찾아 하드웨어가 암호화를 수행하고 있는지 확인할 수 있다. 드라이버는 초기화 시 콘솔 메세지를 전송한다:
[ 1.830397] caam 30900000.crypto: device ID = 0x0a16040100000000 (Era 9)
[ 1.837113] caam 30900000.crypto: job rings = 2, qi = 0
[ 1.849949] caam algorithms registered in /proc/crypto
[ 1.855972] caam 30900000.crypto: caam pkc algorithms registered in /proc/crypto
[ 1.865564] caam_jr 30901000.jr: registering rng-caam
[ 1.870766] Device caam-keygen registered
로그에 메세지가 없으면, 드라이버가 커널에 구성되지 않았거나 디바이스 트리에 CAAM 호환 디바이스 트리 노드가 없는 것이다.
10.3.2 Incrementing IRQs in /proc/interrupts
암호화 요청이 이루어지는 기간이 주어지면, CAAM 하드웨어는 해당 Job Ring에서 완료 알림 인터럽트를 발생시킨다.
root@imx8qxpmek:~# cat /proc/interrupts | grep jr
418: 1059 0 0 0 GICv3 485
Level 31430000.jr2
419: 21 0 0 0 GICv3 486
Level 31440000.jr3
root@imx8qxpmek:~#
인터럽트 발생 횟수가 증가하면, 암호화를 수행하는 데 하드웨어가 사용되고 있는 것이다. 숫자가 증가하지 않으면, 실행 중인 알고리즘이 드라이버에서 지원되는지 확인해야 한다. 알고리즘이 지원되는 경우, 드라이버가 폴링 모드(NAPI 메커니즘)에 있을 가능성이 있으며, debugfs의 하드웨어 통계(inbound/ outbound 바이트 encrypted/protected - 아래 참조)를 모니터링해야 한다.
10.3.3 Verifying the 'self test' fields say 'passed' in /proc/crypto
아래의 항목은 드라이버가 커널 암호화 API를 사용하는 알고리즘에 대한 지원을 성공적으로 등록했음을 의미한다:
name : cbc(des)
driver : cbc-des-caam
module : kernel
priority : 3000
refcnt : 1
selftest : passed
internal : no
type : givcipher
async : yes
blocksize : 8
min keysize : 8
max keysize : 8
ivsize : 8
geniv : <built-in>
드라이버가 지원하는 특정 알고리즘에 대한 테스트 벡터가 존재하지 않을 수도 있다. 드라이버가 지원하지 않는 알고리즘에 대해 테스트 벡터가 존재하지 않을 수 있지만, 커널은 어떤 알고리즘이 테스트되지 않았는지에 대한 메시지를 출력하고 "passed"로 표시한다:
[ 4.647985] alg: No test for
authenc(hmac(sha224),ecb(cipher_null)) (authenc-hmac-sha224-ecb-cipher_null-caam)
[ 4.661181] alg: No test for
authenc(hmac(sha256),ecb(cipher_null)) (authenc-hmac-sha256-ecb-cipher_null-caam)
[ 4.671345] alg: No test for
authenc(hmac(sha384),ecb(cipher_null)) (authenc-hmac-sha384-ecb-cipher_null-caam)
[ 4.681486] alg: No test for
authenc(hmac(sha512),ecb(cipher_null)) (authenc-hmac-sha512-ecb-cipher_null-caam)
10.4 OpenSSL offload
Secure Socket Layer(SSL) 프로토콜은 AES, DES, 3DES와 같이 일반적으로 사용되는 암호화 알고리즘을 사용하여 데이터를 암호화함으로써 전송 중에 데이터를 보호하기 위해 가장 널리 배포된 애플리케이션 프로토콜이다. 암호화 외에도 SHA1, MD5와 같은 hash/digest 알고리즘을 사용하여 메시지 인증 서비스를 제공한다. SSL은 애플리케이션 웹 서버(HTTP)와 다음과 같은 기타 애플리케이션에서 널리 사용된다. 전송 중인 데이터의 무결성을 위해 보호가 필수적인 SMTP, POP3, IMAP 그리고 Proxy 서버에 사용된다. SSL 프로토콜에는 TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3 그리고 DTLS(Datagram TLS)등 다양한 버전이 있다. 이 문서는 OpenSSL을 사용하는 i.MX 플랫폼의 NXP SSL 가속 솔루션에 대해 설명한다:
- OpenSSL 소프트웨어 아키텍처
- 하드웨어 오프로드 지원으로 OpenSSL 빌드
- OpenSSL 오프로드의 예제
10.4.1 OpenSSL software architecture
SSL 프로토콜은 Linux와 BSD 시스템에서 가장 널리 사용되는 라이브러리 배포판인 OpenSSL에서 라이브러리로 구현된다. OpenSSL 라이브러리에는 다음과 같은 여러 서브 컴포넌트가 있다:
- SSL 프로토콜 라이브러리
- SSL 프로토콜 라이브러리 Crypto 라이브러리(Symmetric와 Asymmetric 암호화 지원, digest 지원등)
- Certificate Management
다음 그림은 OpenSSL의 일반적인 상호 연결 아키텍처를 나타낸다. 각 관련 레이어는 Linux User Space와 Linux Kernel Space를 명확하게 구분하여 표시되어 있다.
10.4.2 OpenSSL's ENGINE interface
OpenSSL Crypto 라이브러리는 OpenSSH, OpenVPN, PGP, IKE, XML_SEC와 같은 다양한 애플리케이션에서 사용되는 Symmetric 및 Asymmetric(PKI) 암호화 지원을 제공한다. OpenSSL Crypto 라이브러리는 다음에 대한 소프트웨어 지원을 제공한다:
- Cipher 알고리즘
- Digest 알고리즘
- 난수 생성
- Public Key Infrastructure
소프트웨어 지원 외에도, OpenSSL은 ENGINE 인터페이스를 사용하여 이러한 기능을 하드웨어 가속기에 오프로드할 수 있다. ENGINE 인터페이스는 하드웨어 가속기와 암호화 라이브러리를 통합하는 콜백 훅을 제공한다. 콜백 훅은 하드웨어 가속기와 인터페이스하기 위한 glue 로직을 제공한다. cryptodev 엔진을 사용하면 Linux 커널을 통해 암호와 digest 알고리즘의 일반적인 오프로드가 가능하다.
10.4.3 NXP solution for OpenSSL hardware offloading
OpenSSL 하드웨어 오프로드를 위한 NXP 솔루션에서 다음 레이어를 관찰할 수 있다:
- OpenSSL (사용자 공간): SSL 프로토콜 구현
- cryptodev-engine (사용자 공간): OpenSSL ENGINE 인터페이스를 구현한다. ioctls를 사용하여 cryptodev-linux(/dev/crypto)와 통신하여 커널에서 암호화 작업을 오프로드한다.
- cryptodev-linux (커널 공간): cryptodev-engine의 ioctl 요청을 Linux Crypto API에 대한 호출로 변환하는 Linux 모듈이다.
- AF_ALG는 2.6.38에 도입된 AF_ALG 주소 패밀리를 추가하는 커널 비동기 인터페이스의 netlink 기반이다.
- Linux Crypto API (커널 공간): Linux 커널 암호화 추상 레이어이다.
- CAAM driver (커널 공간): CAAM 암호화 엔진용 Linux 디바이스 드라이버이다.
현재 BSP의 하드웨어에서 오프로드되는 것은 다음과 같다:
- Symmetric Ciphering Operations - AES (CBC, ECB), 3DES (CBC, ECB)
- Digest Operations - SHA (1, 256, 384, 512), MD5
- Public Key Operations - RSA Sign (1k, 2k, 4k) / RSA Verify (1k, 2k, 4k)
10.4.4 Deploying OpenSSL into rootfs
일반적으로, imx-image-full에는 OpenSSL과 cryptodev 모듈이 포함되어 있지만, 다른 Yocto 대상의 경우 사용자가 빌드 디렉토리에서 conf 파일을 업데이트해야 한다. 다음 라인을 추가하여 conf/local.conf를 업데이트 한다:
CORE_IMAGE_EXTRA_INSTALL+="cryptodev-module openssl-bin"
빌드 절차를 다시 시작한다:
bitbake imx-image-full
10.4.5 Running OpenSSL benchmarking tests with cryptodev engine
cryptodev 모듈을 프로브(probe)한다:
root@imx8qxpmek:~# modprobe cryptodev
[17044.896494] cryptodev: driver 1.10 loaded.
root@imx8qxpmek:~# openssl engine
(devcrypto) /dev/crypto engine
(dynamic) Dynamic engine loading support
root@imx8qxpmek:~#
참고:
OpenSSL 1.1.1부터, 해당 모듈이 커널에 삽입된 경우 기본적으로 OpenSSL에서 cryptodev 엔진을 호출한다. 따라서 OpenSSL을 사용하여 SW 벤치마크 테스트만 수행하려면 rmmod cryptodev를 실행하여 cryptodev 모듈을 제거한다.
10.4.5.1 Running OpenSSL benchmarking tests for symmetric ciphering and digest
속도 테스트 파일에서는 대칭 및 digest 작업의 성능을 확인하기 위해 일련의 성능 테스트가 수행된다. 다음은 OpenSSL 테스트 실행에 대해 설명한다:
root@imx8qxpmek:~# openssl speed -engine devcrypto -multi 8 -elapsed -evp aes-128-cbc
Forked child 1
engine "devcrypto" set.
Forked child 2
engine "devcrypto" set.
...
Got: +F:22:aes-128-
cbc:378616.72:1611328.00:5084501.33:13994666.67:10731793.98:16219060.40 from 6
Got: +H:16:64:256:1024:8192:16384 from 7
Got: +F:22:aes-128-
cbc:120773.33:9344.00:3088298.67:13588480.00:31642965.33:16471967.79 from 7
OpenSSL 1.1.1b 26 Feb 2019
built on: Thu Nov 14 13:22:07 2019 UTC
options:bn(64,64) rc4(char) des(int) aes(partial) idea(int) blowfish(ptr)
compiler: aarch64-poky-linux-gcc --sysroot=recipe-sysroot -O2 -pipe -g -
feliminate-unused-debug-types -fmacro-prefix-map=
-fdebug-prefix-map= -fdebug-prefix-map= -fdebug-prefix-map= -
DOPENSSL_USE_NODELETE -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_BN_ASM_MONT
-DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DVPAES_ASM -
DECP_NISTZ256_ASM -DPOLY1305_ASM -DNDEBUG
evp 2242.05k 9681.05k 35017.46k 106866.86k 127787.74k
130077.23k
root@imx8qxpmek:~#
벤치 마크할 수 있는 추가 암호: aes-192-cbc, aes-256-cbc, aes-128-ecb, aes-192-ecb, aes-256-ecb, aes-128-ctr, aes-192-ctr, aes-256-ctr, des-cbc, des-cbc, des-ede3-cbc.
벤치 마크할 수 있는 추가 digest: sha1, sha224, sha256, sha384, sha512, md5.
10.4.6 Running OpenSSL benchmarking tests with AF_ALG engine
다음 커맨드를 실행한다:
Probe the af_alg:
root@imx8mmevk:~# rmmod cryptodev
root@imx8mmevk:~# modprobe af_alg
root@imx8mmevk:~# modprobe algif_hash
root@imx8mmevk:~# modprobe algif_skcipher
root@imx8mmevk:~# modprobe algif_rng
root@imx8mmevk:~# modprobe algif_aead
10.4.6.1 Running OpenSSL benchmarking tests for symmetric ciphering and digest
다음 커맨드를 실행한다:
root@imx8mmevk:~# openssl speed -engine afalg -multi 8 -elapsed -evp aes-128-
cbc
Forked child 0
Forked child 1
engine "afalg" set.
+DT:aes-128-cbc:3:16
engine "afalg" set.
engine "afalg" set.
engine "afalg" set.
...
Got: +H:16:64:256:1024:8192:16384 from 0
Got: +F:22:aes-128-
cbc:333888.00:1359317.33:4248405.33:5720064.00:6160384.00:6176768.00 from 0
Got: +H:16:64:256:1024:8192:16384 from 1
Got: +F:22:aes-128-
cbc:378336.00:1382826.67:5117269.33:5739178.67:6190421.33:6176768.00 from 1
...
OpenSSL 1.1.1k 25 Mar 2021
built on: Thu Mar 25 13:28:38 2021 UTC
options:bn(64,64) rc4(char) des(int) aes(partial) blowfish(ptr)
compiler: aarch64-poky-linux-gcc -mcpu=cortex-a53 -march=armv8-a+crc+crypto
-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security
-Werror=format-security --sysroot=recipe-sysroot -O2 -pipe -g -feliminate
unused-debug-types -fmacro-prefix-map= -fdebug-prefix-
map= -fdebug-prefix-map= -fdebug-
prefix-map= -DOPENSSL_USE_NODELETE -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -
DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -
DVPAES_ASM -DECP_NISTZ256_ASM -DPOLY1305_ASM -DNDEBUG
evp 2682.45k 10842.73k 35957.50k 45915.48k 49722.71k
50135.04k
10.4.7 Running OpenSSL asymmetric tests with PKCS#11 based engine
전제 조건:
- PKCS#11 Library로 PKCS#11 OpenSSL Engine을 실행하려면, 전역 OpenSSL 구성 파일(보통 /etc/ssl/openssl.cnf에 있음)에 다음을 추가한다.
이 라인을 섹션을 정의하기 전에 맨 위에 배치해야 한다:
파일에 다른 openssl_conf = ... 라인이 없는지 확인한다.openssl_conf = openssl_init
이 라인은 파일 맨 아래에 추가해야 한다:
[openssl_init] engines=engine_section [engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = pkcs11 dynamic_path = /usr/lib/engines-3/pkcs11.so MODULE_PATH = /usr/lib/libckteec.so.0 init = 0
dynamic_path 의 값은 PKCS#11 엔진 플러그인이고 MODULE_PATH 값은 NXP PKCS#11 라이브러리이다. engine_id 값은 식별자로 엔진을 선택하기 위한 OpenSSL 애플리케이션을 위한 임의의 식별자이다. - tee-supplicant가 실행 중인지 확인한다.
실행 중이 아니면 다음 커맨드를 실행한다:root@imx8mpevk:~# ps -aux | grep tee root 661 0.0 0.0 76424 1432 ? Ssl May27 0:00 /usr/bin/tee-supplicant
root@imx8mpevk:~# tee-supplicant &
10.4.7.1 Running p11tool to generate key (RSA or EC)
root@imx8mpevk:~# mkdir /etc/gnutls
root@imx8mpevk:~# echo load=`find /usr/lib -name
libckteec.so.0` > /etc/gnutls/pkcs11.conf
root@imx8mpevk:~# p11tool --list-tokens
root@imx8mpevk:~# p11tool --initialize "<token url>" --
label="<token label>"
Enter Security Officer's PIN:
root@imx8mpevk:~# p11tool --list-tokens
root@imx8mpevk:~# p11tool --initialize-pin "<token url>"
Setting user's PIN...
Enter User's new PIN:
Token <toke label> with URL <token url> requires security
officer PIN
Enter PIN:<Security Officer's PIN>
RSA 키를 생성하려면:
root@imx8mpevk:~# p11tool --login --generate-rsa --bits=2048 --
label="RSA-key-2048" --outfile="RSA-key-2048.pub" "<token url>"
--set-pin="<user pin>"
root@imx8mpevk:~# p11tool --login --list-privkeys "<token url>"
--set-pin="<user pin>"
Object 0:
URL: token url private
Type: Private key (RSA-2048)
Label: RSA-key-2048
Flags: CKA_PRIVATE; CKA_NEVER_EXTRACTABLE;
CKA_SENSITIVE;
ID:
bc:8e:f3:ca:95:d6:e7:ae:57:89:43:1f:67:a3:e5:d1:05:d8:5d:66
또는 EC 키를 생성하려면:
root@imx8mpevk:~# p11tool --login --generate-ecc --
curve=secp256r1 --label="ec-key-256" --outfile="ec-key-256.pub"
"<token url>" --set-pin="<user pin>"
root@imx8mpevk:~# p11tool --login --list-privkeys "<token url>"
--set-pin="<user pin>"
Object 0:
URL: token url private
Type: Private key (EC/ECDSA-SECP256R1)
Label: ec-key-256
Flags: CKA_PRIVATE; CKA_NEVER_EXTRACTABLE;
CKA_SENSITIVE;
ID:
9b:54:b4:c5:88:3f:19:44:cb:b2:40:04:46:fa:a0:48:19:eb:0e:70
10.4.7.2 Using OpenSSL from command line
PKCS #11 모듈의 키로 인증서를 생성하려면, 다음 커맨드를 사용한다. 첫 번째 커맨드는 "NXP Semiconductor"에 대한 자체 서명된 인증서를 만든다. 서명은 URL에 지정된 키를 사용하여 수행된다.
root@imx8mpevk:~# openssl req -engine pkcs11 -new -key "<token
url private>" -keyform engine -out req.pem -text -x509 -subj
"/CN=NXP Semiconductor"
Engine "pkcs11" set.
Enter PKCS#11 token PIN for token label:<user pin>
두 번째 커맨드는 요청에 대한 자체 서명된 인증서를 만든다. 인증서 서명에 사용되는 개인 키는 요청을 생성하는 데 사용되는 개인 키와 동일하다.
root@imx8mpevk:~# openssl x509 -engine pkcs11 -signkey "<token
url private>" -keyform engine -in req.pem -out cert.pem
Engine "pkcs11" set.
Enter PKCS#11 token PIN for token label:<user pin>
root@imx8mpevk:~# ls
cert.pem req.pem
10.4.7.3 Running OpenSSL test for RSA
root@imx8mpevk:~# echo "This is plain message 2021-01-18" > plain.text
root@imx8mpevk:~# openssl pkeyutl -engine pkcs11 -encrypt -in
plain.text -out encrypted.enc -inkey cert.pem -certin
root@imx8mpevk:~# openssl pkeyutl -engine pkcs11 -decrypt -in
encrypted.enc -out plain.dec -inkey "<token url private>" -
keyform engine
Engine "pkcs11" set.
Enter PKCS#11 token PIN for token label:<user pin>
root@imx8mpevk:~# cat plain.text
This is plain message 2021-01-18
root@imx8mpevk:~# cat plain.dec
This is plain message 2021-01-18
10.4.7.4 Running OpenSSL test for EC
root@imx8mpevk:~# echo "This is plain message 2021-01-18" > plain.text
root@imx8mpevk:~# openssl pkeyutl -engine pkcs11 -sign -in
plain.text -out cert_ecc.sign -inkey "<token url private>" -
keyform engine
Engine "pkcs11" set.
Enter PKCS#11 token PIN for token label:<user pin>
root@imx8mpevk:~# openssl pkeyutl -verify -in plain.text -
sigfile cert_ecc.sign -inkey ecc_cert.pem -certin
Signature Verified Successfully
10.5 Disk encryption acceleration
디스크 암호화는 정보를 권한이 없는 사람이 쉽게 해독할 수 없는 읽을 수 없는 코드로 변환하여 정보를 보호하는 기술이다. 디스크 암호화는 디스크 암호화 소프트웨어나 하드웨어를 사용하여 디스크나 디스크 볼륨에 있는 모든 데이터 비트를 암호화한다. 이는 데이터 스토리지에 대한 무단 액세스를 방지하는 데 사용된다. i.MX Applications Processors에서 디스크 암호화 시나리오는 다양한 키 보호 방법을 사용하여 다양한 방식으로 구현할 수 있다.
이 섹션에서는 DM-Crypt를 사용하여 블럭 레벨에서 투명한 스토리지 암호화를 실행하는 단계를 설명한다. 아래 그림은 디스크 암호화를 구현하는 소프트웨어 스택을 보여준다.
10.5.1 Enabling disk encryption support in kernel
기본적으로 커널 구성 파일은 Device Mapper 구성과 Crypt Target 지원을 모듈로 활성화한다. 따라서 디스크 암호화 시나리오를 활성화하려면, 보드가 부팅된 후 다음 모듈을 삽입한다:
root@imx8mqevk:/# modprobe dm-mod
[ 266.982638] device-mapper: ioctl: 4.41.0-ioctl (2019-09-16)
initialised: dm-devel@redhat.com
root@imx8mqevk:/# modprobe dm-crypt
root@imx8mqevk:/# dmsetup targets
crypt v1.19.0
striped v1.6.0
linear v1.4.0
error v1.5.0
디스크 암호화 시나리오가 활성화되지 않은 경우 커널의 일부 기능을 활성화해야 한다:
Kernel Configure Tree View Options | Description |
---|---|
< Device Drivers ---> [*] Multiple devices driver support (RAID and LVM) ---> <*> Device mapper support [ ] Device mapper debugging support < > Unstriped target (NEW) <*> Crypt target support <*> Multipath target [*] DM uevents |
Linux 커널에서 DM Crypt 지원 활성화 CONFIG_BLK_DEV_DM=y |
< Cryptographic API ---> <*> User-space interface for hash algorithms <*> User-space interface for symmetric key cipher algorithms <*> User-space interface for AEAD cipher algorithms |
사용자 공간 crypto API를 활성화하여 간단한 cryptsetup 벤치마크 허용 |
Cryptographic API ---> [*] Hardware crypto devices ---> <*> CAAM/SNVS Security Violation Handler (EXPERIMENTAL) <*> Freescale CAAM-Multicore platform driver backend [ ] Enable debug output in CAAM driver <*> Freescale CAAM Job Ring driver backend ---> [*] Register tagged key cryptography implementations with Crypto API |
이것을 선택하면 태그가 지정된 키를 지원하는 알고리즘이 등록되고, black 키가 생성되며 black blob으로 캡슐화된다. |
10.5.2 User space tools for disk encryption
Linux i.MX BSP를 사용할 경우, DM-Crypt에 필요한 모든 필수 사용자 공간 툴이 보드에 이미 설치되어 있다.
필수 사용자 공간 툴이 빌드에 설치되지 않은 경우, conf/local.conf 파일을 편집하여 다음을 추가해야 한다:
CORE_IMAGE_EXTRA_INSTALL+="coreutils keyutils lvm2 e2fsprogs-mke2fs utillinux"
- keyutils: Linux Key 보존 서비스를 관리하는 데 필요한, keyctl을 제공한다.
- lvm2: device-mapper를 관리하기 위한 dmsetup 유틸리티와 라이브러리를 제공한다.
- e2fsprogs-mke2fs: filesystem을 만드는 데 필요한 툴이 포함되어 있다.
- util-linux: 볼륨에서 섹터 수를 읽는 데 필요한 blockdev 유틸리티를 제공한다.
10.5.3 DM-Crypt using CAAM backed keys
Linux Unified Key Setup(LUKS) 모드에서 디스크 암호화 키(마스터 키)를 생성하기 위해 사용되는 솔트와 결합된 암호(passphrase)를 제공한 다음, 제공된 라운드 수만큼 해시 함수를 적용한다. 사용자가 암호화된 볼륨을 마운트하려는 경우 암호(passphrase)를 제공해야 한다. 또는 필요한 암호 해독 정보가 포함된 외장 드라이브에 저장된 키 파일을 제공하는 방법도 있다. 이러한 접근 방식은 임베디드 디바이스 사용 시에는 편리하지 않다.
이러한 blob은 각각 red-blob이나 blackblob에서 plain-key나 black-key를 가져오는 데 사용된다.
DM-Crypt를 사용하는 목적:
- CAAM이 지원하는 신뢰할 수 있는 키
- 사용자가 제공한 암호(passphrase)에서 파생된 키로 마스터 볼륨 키를 암호화하는 메커니즘을 억제하는 데 사용되는 CAAM의 태그 지정 키
Linux OS는 Keyring라는 커널 내 키 관리와 보존 기능을 제공한다. 또한 Keyring을 사용하면 인터페이스에서 키에 액세스하고 사용자 공간에서 추가, 업데이트, 삭제와 같은 작업을 수행할 수 있다.
커널은 ecrypted, trusted, user, logon을 포함하여 몇 가지 기본 유형의 키를 제공한다.
CAAM 드라이버는 다음을 생성하는 데 사용되는 사용자 공간 애플리케이션을 연결한다:
- plain key(일반 )를 red blob으로 캡슐화
- 태그가 지정된 키를 black blob으로 캡슐화
10.5.3.1 DM-Crypt with Trusted keys backed by CAAM
CAAM 상태를 활용하기 위해, DM-Crypt는 커널 keyring에서 CAAM을 통해 생성된 신뢰할 수 있는 키를 가져온다.
Red-Blob에서 캡슐화 해제된 키는 CAAM 상태에 따라 다르다:
- Chain-of-trust가 설정된 상태에서 시스템이 보안 부트로 부팅된 경우, CAAM 상태는 보안 상태이다.
- 보안이 아닌 (또는 손상된) 상태로 시스템이 부팅되는 경우, CAAM 상태는 비-보안 상태이다.
Key Value add:
신뢰할 수 있는 키를 사용하여 보안 상태에서 쓰여진 데이터는 신뢰할 수 없거나 손상된 시스템에서 다시 읽지 않는다.
10.5.3.1.1 Usage
다음 단계는 i.MX 디바이스에서 전체 디스크 암호화를 수행하는 방법을 보여준다.
- 커널 모듈을 삽입한다.
$>: modprobe trusted
- 신뢰할 수 있는 키를 생성한다:
$>: KEYNAME=dm_trust $>: KEY="$(keyctl add trusted $KEYNAME 'new 32' @s)" $>: keyctl pipe $KEY >~/$KEYNAME.blob $>: keyctl list @s
출력:
$>: keyctl list @s 2 keys in keyring: 48178143: ----s-rv 0 0 user: invocation_id 143779047: --alswrv 0 0 trusted: dm_trust
- 보안 볼륨을 생성한다. 물리적 파티션일 수 있다. 이 예에서는 이미지 파일을 사용하고 나중에 마운트한다.
$>: DEV=/dev/loop0 $>: BLOCKS=20 $>: fallocate -l $((BLOCKS*512)) ~/loop0.img $>: losetup -P $DEV ~/loop0.img
- 매핑 테이블 "TABLE"을 생성한다. 위치는:
- Algo는 일반 키(plain key)를 사용하도록 Kernel Crypto API 형식으로 설정된다. Algo/cipher는 cbc(aes)-plain으로 설정된다.
- 키는 길이 32의 신뢰할 수 있는 키로 설정되고 이름은 $KEYNAME으로 내보내진다.
$>: DEV=/dev/loop0 $>: ALGO=capi:cbc(aes)-plain $>: KEYNAME=dm_trust $>: BLOCKS=20 $>: TARGET=crypt $>: TABLE="0 $BLOCKS $TARGET $ALGO :32:trusted:$KEYNAME 0 $DEV 0 1 allow_discards"
- 예를 들어 dmsetup을 사용하여 encrypted이라는 이름의 새로운 device-mapper 디바이스를 만들고, 위에서 만든 매핑 테이블 "TABLE"을 인수로 지정한다.
$>: echo $TABLE | dmsetup create encrypted
- 이전 단계에서 만든 encrypted라는 device-mapper 디바이스를 로드한다.
$>: echo $TABLE | dmsetup load encrypted
- 보안 볼륨을 생성한다.
$>: dd if=/dev/zero of=/dev/mapper/encrypted || true
- 볼륨으로 쓴다.
$>: echo "It works. Congratulations" 1<> /dev/mapper/encrypted
- 디바이스를 마운트 해제한다.
$>: umount /mnt/encrypted/
- device-mapper 디바이스를 비활성화한다.
$>: dmsetup remove encrypted
보드를 다시 시작한다:
$>: reboot
- 다음 부팅 시 커널 모듈을 삽입한다.
$>: modprobe trusted Step 11: Load the trusted key: $>: KEYNAME=dm_trust $>: keyctl add trusted $KEYNAME "load $(cat ~/$KEYNAME.blob)" @s $>: keyctl list @s
출력:
$>: keyctl list @s 2 keys in keyring: 48178143: ----s-rv 0 0 user: invocation_id 143779047: --alswrv 0 0 trusted: dm_trust
- 매핑 테이블 "TABLE"를 생성한다. 위치는:
- Algo는 일반 키(plain key)를 사용하도록 Kernel Crypto API 형식으로 설정된다. Algo/cipher는 cbc(aes)-plain으로 설정된다.
- 키는 길이 32의 신뢰할 수 있는 키로 설정되고 이름은 $KEYNAME으로 내보내진다.
$>: DEV=/dev/loop0 $>: ALGO=capi:cbc(aes)-plain $>: KEYNAME=dm_trust $>: BLOCKS=20 $>: TARGET=crypt $>: TABLE="0 $BLOCKS $TARGET $ALGO :32:trusted:$KEYNAME 0 $DEV 0 1 allow_discards"
- encrypted 디바이스를 마운트한다.
$>: losetup -P $DEV ~/loop0.img
- dmsetup을 사용하여 볼륨을 암호화하려면 매핑 테이블 "TABLE"을 지정한다.
$>: echo $TABLE | dmsetup create encrypted $>: echo $TABLE | dmsetup load encrypted
- 내용이 이전 부팅에서 기록된 것과 동일한지 확인하기 위해 디바이스에서 읽는다.
$>: hexdump -C /dev/mapper/encrypted
10.5.3.2 DM-Crypt with CAAM’s tagged key
DM-Crypt는 오프라인 암호 해독으로부터 스토리지 볼륨을 보호하기 위해 태그가 지정된 키를 활용할 수도 있다. 또한, 퓨즈에 동일한 OTPMK가 저장된 디바이스에서만 볼륨을 열 수 있다. 자세한 내용은 특정 SoC에 대한 Security Reference Manual을 참조한다.
태그가 지정된 키 기능은 CAAM의 black key 메커니즘을 기반으로 한다. black key는 SoC 외부 메모리에서 키를 쓰거나 읽는 동안 버스 스누핑(bus snooping)으로부터 사용자 키를 보호한다. CAAM은 AES-ECB와 AES-CCM이라는 두 가지 black key 캡슐화 체계를 지원한다.
AES-ECB 암호화와 관련하여, 데이터는 16바이트 길이의 배수이며 빠른 암호 해독을 위한 것이다.
AES-CCM 모드는 AES-ECB 모드만큼 빠르지는 않지만, 캡슐화된 키의 무결성을 보장하는 "MAC tag"(무결성 검사 값)를 포함한다. CCM으로 암호화된 black key는 항상 캡슐화된 키(nonce value + MAC tag)보다 12바이트 이상 길다.
black key는 세션 키이므로 전원 사이클(전원 ON/OFF)에 안전하지 않다. CAAM의 Blob 메커니즘은 시스템 전원 주기 동 사용자 정의 데이터를 보호하는 방법을 제공한다. 이것은 기밀성과 무결성 보호를 모두 제공한다. 보호할 데이터는 암호화되어 SoC의 전원이 꺼지기 전에 비휘발성 스토리지에 안전하게 저장할 수 있다.
다음 다이어그램은 태그가 지정된 키를 사용하여 전체 디스크 암호화 지원을 추가하기 위해 변경된 사항을 보여준다. CAAM 드라이버는 ECB와 CBC blacken key인 tk(ecb(aes)), tk(cbc(aes))를 사용하여 커널에 새로운 Cryptographic 변환을 등록한다. tk 접두사는 태그가 지정된 키를 나타낸다.
$ ./caam-keygen
CAAM keygen usage: caam-keygen [options]
Options:
create <key_name> <key_enc> <key_mode> <key_val>
<key_name> the name of the file that will contain the black
key.
A file with the same name, but with .bb extension, will
contain the black blob.
<key_enc> can be ecb or ccm
<key_mode> can be -s or -t.
-s generate a black key from random with the size given in
the next argument
-t generate a black key from a plaintext given in the next
argument
<key_val> the size or the plaintext based on the previous
argument (<key_mode>)
import <blob_name> <key_name>
<blob_name> the absolute path of the file that contains the
blob
<key_name> the name of the file that will contain the black
key.
기본적으로 키와 Blob은 /data/caam/인 KEYBLOB_LOCATION에 생성된다.
나중에 CAAM 태그 키가 Linux 키 보존 서비스에 추가되고, keyctl과 같은 사용자 공간 애플리케이션에서 관리된다. black blob은 모든 비휘발성 저장소에 저장할 수 있다.
dmsetup(libdevmapper 패키지의 일부)은 매우 낮은 레벨의 구성을 수행하기 위한 강력한 툴이며, 암호화된 볼륨을 관리하는 데 사용된다.
10.5.4 Usage
다음은 i.MX 디바이스에서 전체 디스크 암호화를 수행하는 단계이다.
- 디바이스를 부팅한 후, Tagged Key를 사용한 암호화 변환이 등록되어 있는지 확인한다.
root@imx8mqevk:~# grep -B1 -A2 tk- /proc/crypto|grep -v kernel name : tk(ecb(aes)) driver : tk-ecb-aes-caam priority : 3000 -- name : tk(cbc(aes)) driver : tk-cbc-aes-caam priority : 3000 root@imx8mqevk:~#
그러면 caam-keygen 애플리케이션을 사용할 수 있다:
root@imx8mmevk:~# cd /; find -name "caam-keygen" ./usr/bin/caam-keygen ./dev/caam-keygen ./sys/class/misc/caam-keygen ./sys/devices/virtual/misc/caam-keygen
지금은 AES 알고리즘만 지원한다. 따라서 암호화/복호화에 허용되는 키의 크기는 16, 24, 32바이트이다. - DM-Crypt 활성화되어 있는지 확인한다.
root@imx8mqevk:~# dmsetup targets crypt v1.19.0 striped v1.6.0 linear v1.4.0 error v1.5.0
위 항목 중 누락된 항목이 있으면, 커널 구성을 확인하거나 커널에서 디스크 암호화 지원 활성화 섹션을 참조한다. - 그런 다음 정의된 일반 키(plain key)나 임의로 생성할 수 있는 키인 black key를 디바이스에 제공한다.
다음은 크기가 16바이트인 일반 텍스트(plaintext)에서 ECB로 암호화된 black key의 예이다:
root@imx8mqevk:~# ./caam-keygen create fromTextkey ecb -t 0123456789abcdef
결과는 파일 시스템(기본 위치는 /data/caam)에 기록된 Tagged Key와 Blob 파일이다. 사용되는 키 암호화 체계는 ECB이다.
root@imx8mqevk:~# ls -la /data/caam/ total 16 drwxr-xr-x 2 root root 4096 Aug 25 15:38 . drwxr-xr-x 3 root root 4096 Aug 25 15:38 .. -rw-r--r-- 1 root root 36 Aug 25 15:38 fromTextkey -rw-r--r-- 1 root root 96 Aug 25 15:38 fromTextkey.bb
다음으로 keyctl을 사용하여 키 보존 서비스에 키를 추가한다:
root@imx8mqevk:~# cat /data/caam/fromTextkey | keyctl padd logon logkey: @s 876928653
- 보안 볼륨을 생성한다. 이는 물리적 파티션일 수 있다. 이 예에서는 다음을 사용한다. 이미지 파일을 만들고 나중에 마운트한다.
root@imx8mqevk:~# dd if=/dev/zero of=encrypted.img bs=1M count=32 32+0 records in 32+0 records out 33554432 bytes (34 MB, 32 MiB) copied, 3.20227 s, 10.5 MB/s root@imx8mqevk:~# root@imx8mqevk:~# losetup /dev/loop0 encrypted.img root@imx8mqevk:~#
- dmsetup을 사용하여, 예를 들어 encrypted라는 이름의 새로운 device-mapper 디바이스를 만들고 매핑 테이블을 지정한다. 이 테이블은 stdin이나 인수로 제공될 수 있다.
root@imx8mqevk:~# dmsetup -v create encrypted --table "0 $(blockdev --getsz /dev/loop0) crypt capi:tk(cbc(aes))- plain :36:logon:logkey: 0 /dev/loop0 0 1 sector_size:512" Name: encrypted State: ACTIVE Read Ahead: 256 Tables present: LIVE Open count: 0 Event number: 0 Major, minor: 253, 0 Number of targets: 1
다음은 매핑 테이블에 대한 분석이다:
- start는 섹터 0부터 암호화를 시작한다는 의미한다.
- size는 섹터 단위의 볼륨 크기이다.
- blockdev는 디바이스의 섹터 수를 가져온다.
- target은 crypt이다.
- cipher는 Tagged Key를 사용하기 위해 Kernel Crypto API 형식으로 설정된다. cipher가 capi:tk(cbc(aes))-plain으로 설정하고 키가 :36:logon:logkey:로 설정하면 CAAM Tagged Key 변환과 함께 로그온 키를 사용하게 된다.
- IV는 32비트 리틀엔디안 버전의 섹터 번호인 일반 Initialization Vector로 정의된 초기화 벡터이며, 필요한 경우 0으로 채워진다.
- key type은 Logon Key로 설정된 Keyring 키 서비스 유형이다. 36은 바이트 단위의 키 크기이다.
- key name은 로드할 키를 식별하기 위한 키 디스크립션이다.
- IV offset은 IV 값을 계산하기 위해 섹터 번호에 더할 값이다.
- device는 백엔드로 사용할 디바이스의 경로이다. 여기에는 암호화된 데이터가 포함되어 있다.
- offset은 디바이스의 섹터 0에서 시작하는 암호화된 데이터를 나타낸다.
- optional parameters는 선택적 파라미터의 수를 나타낸다.
- sector_size는 암호화 섹터 크기를 지정한다.
생성된 디바이스는 /dev/mapper에 나타난다:
root@imx8mqevk:~# dmsetup table --showkey encrypted 0 65536 crypt capi:tk(cbc(aes))-plain :36:logon:logkey: 0 7:0 0
- 디바이스에 파일 시스템을 만든다.
root@imx8mqevk:~# mkfs.ext4 /dev/mapper/encrypted mke2fs 1.45.3 (14-Jul-2019) Creating filesystem with 32768 1k blocks and 8192 inodes Filesystem UUID: 3ba01ad8-ba03-4389-a955-5136b3173c35 Superblock backups stored on blocks: 8193, 24577 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information:l done
- 마운트 지점을 설정한다.
root@imx8mqevk:~# mkdir /mnt/encrypted
- 매핑된 디바이스를 마운트한다.
root@imx8mqevk:~# mount -t ext4 /dev/mapper/encrypted /mnt/ encrypted/ [ 9409.936183] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null) [ 9409.943892] ext4 filesystem being mounted at /mnt/ encrypted supports timestamps until 2038 (0x7fffffff)
- 디바이스에 기록한다.
root@imx8mqevk:~# echo "This is an encrypt with black key (ECB from text 16 bytes key size) test of full disk encryption on i.MX" > /mnt/encrypted/readme.txt
- 디바이스를 언마운트한다.
root@imx8mqevk:~# umount /mnt/encrypted/
- device-mapper 디바이스를 비활성화한다.
root@imx8mqevk:~# dmsetup remove encrypted
- 보드를 다시 시작한다.
root@imx8mqevk:~# reboot ... root@imx8mqevk:~#
- blob에서 키를 가져와 키 보존 서비스에 추가한다.
root@imx8mqevk:~# ./caam-keygen import /data/caam/ fromTextkey.bb importKey root@imx8mqevk:~# cat /data/caam/importKey | keyctl padd logon logkey2: @s 605536287 root@imx8mqevk:~# ls -la /data/caam/ total 20 drwxr-xr-x 2 root root 4096 Aug 25 15:47 . drwxr-xr-x 3 root root 4096 Aug 25 15:38 .. -rw-r--r-- 1 root root 36 Aug 25 15:38 fromTextkey -rw-r--r-- 1 root root 96 Aug 25 15:38 fromTextkey.bb -rw-r--r-- 1 root root 36 Aug 25 15:47 importKey root@imx8mqevk:~#
- 암호화된 디바이스를 마운트한다.
root@imx8mqevk:~# losetup /dev/loop0 encrypted.img root@imx8mqevk:~#
- dmsetup을 사용하여 볼륨을 암호화할 매핑 테이블을 지정한다.
root@imx8mqevk:~# dmsetup -v create encrypted --table "0 $(blockdev --getsz /dev/loop0) crypt capi:tk(cbc(aes))- plain :36:logon:logkey2: 0 /dev/loop0 0 1 sector_size:512" Name: encrypted State: ACTIVE Read Ahead: 256 Tables present: LIVE Open count: 0 Event number: 0 Major, minor: 253, 0 Number of targets: 1
- 마운트.
root@imx8mqevk:~# mount /dev/mapper/encrypted /mnt/encrypted/ [ 191.961828] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null) [ 191.969533] ext4 filesystem being mounted at /mnt/ encrypted supports timestamps until 2038 (0x7fffffff) root@imx8mqevk:~
- 디바이스를 읽는다.
root@imx8mqevk:~# cat /mnt/encrypted/readme.txt This is an encrypt with black key (ECB from text 16 bytes key size) test of full disk encryption on i.MX. root@imx8mqevk:~#
- 디바이스를 마운트 해제하고 device-mapper 디바이스를 비활성화한다.
root@imx8mqevk:~# umount /mnt/encrypted/; dmsetup remove encrypted
10.6 crypto_af_alg application support
10.6.1 Prerequisites
Black Blob에서 black key를 가져오려면, caam-keygen 애플리케이션이 필요하다. caam-keygen 애플리케이션이 이미 /usr/bin에 있는지 확인한다.
10.6.2 Building the kernel
10.6.2.1 Kernel configuration
- CONFIG_CRYPTO_USER_API
- CONFIG_CRYPTO_USER_API_HASH
- CONFIG_CRYPTO_USER_API_SKCIPHER
- CONFIG_CRYPTO_USER_API_RNG
- CONFIG_CRYPTO_USER_API_AEAD
black key 지원과 Linux 커널용 AF_ALG 소켓 인터페이스가 포함된 부팅 가능한 이미지를 가져온다. 또는 https://github.com/nxp-imx/linux-imx/에서 가져온 커널을 빌드한다.
10.6.2.2 Building a toolchain
caam-decrypt 애플리케이션 소스를 크로스 컴파일하는 툴체인을 빌드한다. 자세한 내용은 i.MX Yocto Project User's Guide(IMXLXYOCTOUG)를 참조한다.
$ wget https://developer.arm.com/-/media/Files/downloads/gnu-a/
8.2-2019.01/gcc-arm-8.2-2019.01-x86_64-aarch64-elf.tar.xz
$ tar xf gcc-arm-8.2-2019.01-x86_64-aarch64-elf.tar.xz
10.6.2.3 Cross compiling the user space sources
미리 준비한 툴체인을 사용하여 크로스 컴파일을 위한 환경을 설정한다.
- 툴체인 폴더에서 환경을 설정한다.
$ export CROSS_COMPILE=<path to toolchain>/bin/aarch64-linux-gnu- $ export CC=${CROSS_COMPILE}gcc $ export LD=${CROSS_COMPILE}ld
- caam-decrypt 사용자 공간 애플리케이션을 빌드한다. 소스 폴더로 이동하여 다음을 실행한다:
$ make clean $ make
10.6.3 Usage
이전에 생성된 이미지로 디바이스가 성공적으로 부팅되면, caam-decrypt를 사용하여 파일에 저장된 암호화된 데이터를 복호화할 수 있다.
$ ./caam-decrypt
Application usage: caam-decrypt [options]
Options:
<blob_name> <enc_algo> <input_file> <output_file>
<blob_name> the absolute path of the file that contains the black blob
<enc_algo> can be AES-256-CBC
<input_file> the absolute path of the file that contains input data
initialization vector(iv) of 16 bytes prepended
size of input file must be multiple of 16
<output_file> the absolute path of the file that contains output data
10.6.4 Use case example
$ caam-decrypt myblob AES-256-CBC my_encrypted_file output_decrypted
위치 정보:
- myblob: 생성된 black key blob. caam-keygen 애플리케이션은 black blob에서 black key를 가져온다. 이 black key는 복호화를 위해 CAAM에서 사용된다.
- AES-256-CBC: 현재 암호 복호화 작업에 사용되는 유일하게 지원되는 대칭 알고리즘이다. 암호화된 데이터는 동일한 알고리즘을 사용해야 한다.
- my_encrypted_file: 파일에 저장된 암호화된 데이터. 암호화 시 사용되는 16바이트의 initialization vector(iv)는 암호화된 데이터 앞에 추가되어야 한다.
ㅁ - output_decrypted: 성공적인 복호화 작업 후 복호화된 데이터를 포함한다.
10.7 Kernel TLS offload
Linux 커널은 TLS 연결 오프로드 인프라를 제공한다. TCP 연결이 ESTABLISHED 상태가 되면, 사용자 공간은 TLS Upper Layer Protocol(ULP)을 활성화하고 암호화 연결 상태를 설치할 수 있다. 사용자 대면 인터페이스에 대한 자세한 내용은 Kernel TLS의 TLS 설명서를 참조한다.
10.7.1 Prerequisites
다음 커맨드를 사용하여 OpenSSL 버전을 확인한다. 이는 3.0.0 이상이어야 한다.
openssl version
10.7.2 Running Kernel TLS test
서버에서 RSA 2048 키, 인증서를 생성하고 openssl s_server를 실행한다:
root@imx8mmevk:~# openssl req -new -newkey rsa:2048 -nodes -keyout rsa.key -out rsa.csr
root@imx8mmevk:~# openssl x509 -req -sha256 -days 365 -in rsa.csr -signkey rsa.key -out server.pem
root@imx8mmevk:~# openssl s_server -key rsa.key -cert server.pem -accept 443 -ssl_config ktls
Using default temp DH parameters
ACCEPT
다른 터미널에서 openssl s_client를 실행한다:
root@imx8mmevk:~# openssl s_client -quiet -connect <server ip>:443 -tls1_2 -ssl_config ktls -cipher 'ECDHE-RSA-AES256-GCM-SHA384'
Connecting to <server ip>
Can't use SSL_get_servername
...
Using Kernel TLS for sending
Using Kernel TLS for receiving
<write some message and enter>
전체 클라이언트 로그를 보려면 -quiet를 제거한다. TLSv1.2에서 Kernel TLS는 다음 암호화를 지원한다:
- AES128-GCM-SHA256
- AES256-GCM-SHA384
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-RSA-AES256-GCM-SHA384
10.8 IMA/EVM on i.MX SoCs
Integrity Measurement Architecture (IMA): 파일이 실수로 또는 악의적으로 변경되었는지 감지하는 데 사용되는 Linux 무결성 서브시스템이다. 확장된 속성(security.ima)으로 저장된 "good" 값에 대해 파일의 측정값을 평가하여 로컬 파일 무결성 검사를 수행한다. 파일의 확장된 속성(security.ima)은 해당 콘텐츠의 해시 값(SHA-1, SHA-256 또는 SHA-512)이다. IMA는 런타임 시 시스템에 로드되는 모든 실행 파일과 기타 민감한 시스템 파일에 대한 해시 값 목록을 유지 관리한다.
Extended Verification Module (EVM): 무결성 공격으로부터 파일의 확장된 속성을 보호한다. 확장된 보안 속성(security.evm)은 security.selinux, security.SMACK64, security.ima와 같은 파일과 관련된 다른 확장된 속성에 대한 HMAC 값을 저장한다.
EVM은 커널 키 보존 시스템에 의존하며 HMAC 작업을 위해 evm-key라는 암호화된 키가 필요하다. 키는 keyctl 유틸리티를 사용하여 루트 사용자 keyring에 로드된다. securityfs/evm 파일에서 활성화 플래그를 설정하여 EVM을 활성화한다.
정상적인 보안 부트 프로세스에서, 영구적인 스토리지 디바이스에 마운트된 루트 파일 시스템의 컨텐츠는 어떠한 메커니즘으로도 검증되지 않으므로 신뢰할 수 없다. 신뢰할 수 없는 rootfs 콘텐츠의 악의적인 변경 사항은 감지되지 않는다. IMA EVM은 rootfs의 무결성을 확인하는 Linux 표준 메커니즘이다. 파일 속성과 해당 컨텐츠에 대한 무결성 검사는 실행 전에 Linux IMA EVM 모듈에서 수행된다. IMA EVM은 사용자의 keyring에 로드된 암호화된 키에 따라 달라진다. 루트 사용자 keyring에 키를 로드하고 EVM을 활성화하는 것은 일반적으로 initramfs 이미지를 사용하여 수행된다. initramfs 이미지는 보안 부트 프로세스를 사용하여 검증되고 신뢰 체인의 일부가 된다. 시스템에서 EVM이 성공적으로 활성화된 후, initramfs는 스토리지 디바이스에 마운트된 기본 rootfs로 제어를 전환한다.
10.8.1 EVM Key on user keyrings
EVM 보안 속성은 사용자 keyring에 로드된 암호화된 키(evm-key라고 하는)에 따라 달라진다. 암호화된 키는 마스터 키를 사용하여 커널에서 파생된다. 마스터 키는 다음 유형일 수 있다:
- User-Key
- Secure-Key
- Trusted-Key
안전하고 신뢰할 수 있는 키는 보안 강화를 위해 하드웨어 보안 엔진을 사용하여 파생되는 반면, 사용자 키의 보안은 하드웨어에 관계없이 사용자 정의 메커니즘에 의존한다. 보안 키는 Layerscape의 SEC(일명 CAAM)를 사용하여 파생된다. 신뢰할 수 있는 키는 TPM을 지원하는 플랫폼에서 사용할 수 있다.
암호화된 키는 HMAC 키 역할을 하며 이후에 다른 보안 속성에 대한 HMAC 값(security.evm)을 계산하는 데 사용된다. 이 키는 커널에 의해 내부적으로 저장되며 사용자는 해당 blob만 볼 수 있다.
10.8.2 Modes of operation in IMA EVM
IMA/EVM은 두 가지 모드로 활성화된다:
- Fix 모드
- Enforce 모드
IMA EVM이 있는 시스템을 활성화하려면, 아래 설명된 대로 두 모드를 순서대로 구현해야 한다:
- bootargs의 ima_appraise=fix와 evm=fix를 사용하여 fix 모드에서 시스템을 부팅해야 한다. 루트 keyring에 키를 로드한 후 전체 파일 시스템에 보안 속성 레이블이 지정된다. fix 모드에서, INTEGRITY_UNKNOWN로 지정된 모든 파일은 적절한 속성 값으로 레이블이 지정된다. 이 모드는 필드 배포를 위해 시스템을 준비하는 동안 한 번만 실행해야 한다.
- fix 모드 실행이 성공적으로 완료된 후 시스템은 enforce 모드에서 IMA EVM을 부팅해야 한다. enforce 모드는 bootargs의 ima_appraise=enforce를 설정하여 활성화한다. enforce 모드에서 파일은 "good" 값에 대해 측정된다. 계산된 보안속성 값과 저장된 값이 일치하지 않는 경우 해당 파일에 대한 접근이 거부된다. 필드에 있는 동안 시스템 부트는 enforce 모드에서만 수행된다.
10.8.3 Build Steps
initramfs 빌드를 위해 https://bitbucket.sw.nxp.com/projects/IMX/repos/metaimx-integrity/browse(링크 깨짐)에 언급된 지침을 따른다.
- integrity-image-minimal-<board-name>-<build_no>.rootfs.tar.zst를 빌드한 후, tar.zst를 추출(압축 해제)한다.
- 다음 커맨드를 사용하여 추출된 디렉터리를 CPIO 파일로 변환한다:
find . | cpio -H newc -o > ../<rootfs_name>.cpio
- 다음 커맨드를 사용하여 위에서 빌드된 rootfs를 gzip으로 압축한다:
gzip ../<rootfs_name>.cpio
- 다음 커맨드를 사용하여 gzip로 압축된 rootfs를 Ramdisk 파일로 변환한다:
mkimage -A arm -O linux -T ramdisk -d <gzipped_rootfs> <Ramdisk_name>
- i.MX 보드에 커널 이미지, dtb 파일, Ramdisk 파일을 플래싱한다.
- fix 모드의 경우, 현재 bootargs에 다음 bootargs를 추가한다:
rootwait rw lsm=integrity rootflags=i_version ima_appraise=fix ima_policy=appraise_tcb evm=fix initrd=<Ramdisk path>
- enforce 모드의 경우, 현재 bootargs에 다음 bootargs를 추가한다:
rootwait rw lsm=integrity rootflags=i_version ima_appraise_tcb ima_appraise=enforce initrd=<Ramdisk path>"
10.8.4 Steps to verify IMA EVM feature
IMA EVM이 enforce 모드에서 성공적으로 활성화되었는지 확인하려면 다음 검사를 수행해야 한다.
- 신뢰할 수 있는 키와 암호화된 키는 커널 이미지에서 활성화된다. 다음 커널 로그는 보안 키와 암호화된 키가 성공적으로 등록되었는지 확인한다.
[ 6.893635] Key type trusted registered [ 6.905123] Key type encrypted registered
- IMA EVM은 커널 이미지에서 활성화된다. 다음 커널 로그는 IMA EVM이 활성화되었는지 확인한다.
[ 6.909218] ima: No TPM chip found, activating TPM-bypass! [ 6.914738] ima: Allocated hash algorithm: sha1 [ 6.962804] evm: HMAC attrs: 0x1
- 시스템은 enforce 모드에 있다. initramfs와 커널의 다음 로그는 enforce 모드가 활성화되었는지 확인한다.
[ 8.248060] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none. Loading blobs [ 8.294368] evm: key initialized
- 파일에 대한 EVM 속성은 getfattr 유틸리티를 사용하여 확인할 수 있다.
root@imx8ulpevk:~# getfattr -d -m . /path/to/file
- 파일 컨텐츠를 변경하면 보안 속성이 성공적으로 평가된다. 다음 커맨드는 평가 기능을 확인한다.
root@imx8ulpevk:~# vim test_file // write contents "abc" root@imx8ulpevk:~# getfattr -d -m . /path/to/test_file root@imx8ulpevk:~# vim test_file // write contents "abcd" root@imx8ulpevk:~# getfattr -d -m . /path/to/test_file
'NXP i.MX SoC Family > i.MX Linux User`s Guide (IMXLUG)' 카테고리의 다른 글
i.MX Linux User's Guide (IMXLUG) - DDR Performance Monitor (0) | 2023.03.30 |
---|---|
i.MX Linux User's Guide (IMXLUG) - Connectivity (0) | 2023.03.28 |
i.MX Linux User's Guide (IMXLUG) - Graphics (0) | 2023.03.10 |
i.MX Linux User's Guide (IMXLUG) - Audio (0) | 2023.03.06 |
i.MX Linux User's Guide (IMXLUG) - Multimedia (0) | 2023.02.24 |