레이블이 Security인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Security인 게시물을 표시합니다. 모든 게시물 표시

10/21/2022

ESP32 Secure Boot 와 OTP

1. ESP32 Secure Boot 기본개념

  • ARM/ESP32 Secure Boot 관련비교 내용 
ARM의 Secure Boot 와 ESP32의 Secure Boot의 기본개념을 설명 
반드시 이해를 해야하며, 이를 이해해야 아래의 내용도 이해가능 

  • ESP32의 Startup Boot Flow
  1. 1st stage bootloader : ESP32 내부에 존재하는 Bootloader로 ROM에 이미 저장
  2. 2nd stage bootloader: ESP32의 SPI Flash 저장되어진 실제적인 bootloader image 이며 Partition table 접근가능
  3. application image: app image로 factory or ota 영역에 저장되는 application image

상위와 같이 ESP32는 Booting하며, User가 신경써야 할 부분은 2nd StageApplication image이다. 


1.1 ESP32 Secure Boot Version  

Espressif에서는 Secure Boot V1, V2을 제공하고 있지만, V2 더 권장하고 있으며, 다음과 같은 차이가 존재한다. 

  1. SecureBoot v1 : ESP32 Silicon Version1/2에서 지원가능
  2. SecureBoot v2 : ESP32 Silicon Version3에서 지원가능

  • ESP32 Secure Boot v1 for ESP32 Revision1/2
  1. AES-256-ECB 방식으로 bootloader Encoding/Decoding  
  2. ECSDA Signature 기반으로 appImage Signing/Verification  Image검증  
  3. OTP(eFUSE) 의 Block 2에  AES 256 bit 저장이용 
  4. OTP(eFUSE) 의 ABS_DONE_0 설정 

  • ESP32 Secure Boot v2 for ESP32 Revision3
  1. RSA3072 Key 기반으로 Signature 기반 bootloader Signing/Verification  Image검증  
  2. RSA3072 Key 기반으로 Signature 기반 appImage Signing/Verification  Image검증     
  3. OTP(eFUSE) 의 Block 2에 SHA-256 bit digest 이용하여 RSA3072 Public Key 검증 
  4. OTP(eFUSE) 의 ABS_DONE_1 설정 


1.2  Secureboot 의 Signing 과 Verfication 이해 

Secure Boot의 기본개념인 Signing 과 Verfication을 알아보도록 하자 
흔히, 비대칭키를 이용하여 Sign을 하여, Signature 생성하고, 이를 검증(Verfication)하는 것이다.

Android System의 Sign 과 Vefication 이해 

암호화 기본개념 

  • Secure Boot Signing
  1. 비대칭키 기반 사용 (RSA,ECDSA)
  2. Build를 한 후 image를 생성할때 Private Key로 Signature를 생성

  • Secure Boot Verification 
  1. 비대칭키 기반 사용 (RSA,ECDSA)
  2. 이미 생성된 Signature를 Public Key를 이용하여 이를 검증 

2. ESP32 Secure Boot 설정 과 진행 


우선 Signature를 만들기 위해서, 즉 Signing을 위한 Key가 필요하다. 


2.1 RSA Signing Key 생성방법 


Window용 ESP-IDF가 버그가 있어 아래와 같이 export.bat 수정하도록 한다.  
아래는 Powershell 용이 아니라 Command 용이므로 참고하도록하자. 

  • ESP-IDF 버그 수정 (v.4.2.3)
수정후 espsecure.py 사용가능
cd  %userprofile%\esp\esp-idf\export.bat  //수정 export.bat (Window에서 espsecure.py 미지원)

....
DOSKEY idf.py=python.exe "%IDF_PATH%\tools\idf.py" $*
DOSKEY esptool.py=python.exe "%IDF_PATH%\components\esptool_py\esptool\esptool.py" $*
DOSKEY espefuse.py=python.exe "%IDF_PATH%\components\esptool_py\esptool\espefuse.py" $*
DOSKEY espsecure.py=python.exe "%IDF_PATH%\components\esptool_py\esptool\espsecure.py" $*
DOSKEY otatool.py=python.exe "%IDF_PATH%\components\app_update\otatool.py" $*
DOSKEY parttool.py=python.exe "%IDF_PATH%\components\partition_table\parttool.py" $*

echo Checking if Python packages are up to date...
python.exe "%IDF_PATH%\tools\check_python_dependencies.py"
if %errorlevel% neq 0 goto :end

echo.
echo Done! You can now compile ESP-IDF projects.
echo Go to the project directory and run:
echo.
echo   idf.py build
echo.
....


RSA Signing Key를 꼭 espsecure.py로 생성할 필요는 없으며, openssl로 쉽게 생성가능.

  • RSA3072 Key 생성방법-A 
openssl을 이용하여  Singing Key 생성 방법 
$ openssl genrsa -out my_secure_boot_signing_key.pem 3072
$ cp ./my_secure_boot_signing_key.pem /mnt/d/Works/   

  • RSA3072 Key 생성방법-B
espsecure.py 이용하여 쉽게 생성가능하며, 각 Version 별로 설정가능  
$ espsecure.py generate_signing_key -v2 test1.pem   
$ espsecure.py generate_signing_key -v1 test1.pem   
$ espsecure.py sign_data --version 2 --keyfile my_secure_boot_signing_key.pem  --output ./build/app_sign.bin ./build/app.bin 

  • ESP SecureBoot Version1
ESP32의 경우, Revision3 부터 사용권장
PEM 방식으로 ECDSA Signing/Verification 동작 

ESP32 SecureBootV1 Manual 

  • ESP SecureBoot Version2 
이를 좀 더 권장하며, ESP32 ECO3 이상에서 사용가능하며, RSA-PSS 방식이라고 말한다.
PEM 의 RSA3072 기반으로 Signing/Verfication 방식
OTP(eFUSE, One Time Programming)  Block2 의 Secure Boot에 RSA Public Key의 Hash를 넣는 구조

ESP32의 Secure Boot 기본이해 

  • ESP32 와 외부 Security Chip 사용 
ESP32에서 ECDSA의 Sign/Verify를 사용하기 위해서 외부 Chip를 사용 
이전에 설명한 CMVP/KCMVP 기능이라고 생각하면 될 것 같으며, 확장기능으로 이를 이용하여 TLS도 가능하다 


2.2 OTP(eFuse) 구조 와 역할 

ESP32 의 경우, 1024bit 의 OTP(One Time Programmable, eFUSE)를 가지고 있고, 각 Block은 256bit로 총 4개로 나누어 분리하여 사용하도록 한다. 
주의 해야할 것은 OTP(One Time Programmable) 한 번만 Write가 가능하므로, 신중하게 하도록하자. 
실패하면, 쓸모가 없어진다. 

  • OTP(eFUSE) 구조 

  • OTP(One Time Programable,eFuse) Manual 
ESP-IDF Version에 따라 조금씩 다르므로 각 버전에 맞게 참조하도록 하자 

  • ESP32 burn-efuse 설명 


  • ESP32 OTP 사용방법 
설정하는 방법은 현재 Command 중심으로 하는게 제일 편하며, ESP-IDF 개발환경에서 VS Code용 EFUSE Exploerer를 별도로 제공을 해주고 있다. 
  1. UI 중심: VS Code EFUSE Exploerer
  2. Command 중심 아래 참조 


2.3 OTP(eFuse) Command 기반 사용법 

실제로 ESP32에서 제공하는 eFuse, OTP 설정값들을 확인해보고, 제어를 해보도록하자. 

  • Window에서 ESP-IDF 활성화   
ESP-IDF가 현재 venv기반의 Python으로 되어있으므로 이를 활성화 부터 해야한다.

Command로 할 경우, 
%userprofile%\.espressif\python_env\idf4.2_py3.8_env\Scripts\activate.bat
%userprofile%\esp\esp-idf\export.bat

PowerShell 할 경우,
$Env:userprofile\.espressif\python_env\idf4.2_py3.8_env\Scripts\activate.ps1
$Env:userprofile\esp\esp-idf\export.ps1

Window 용 PowerShell 관련내용 
주의, Powershell의 경우 Version 따라 동작이 많이 다르며, 점차 Linux 처럼 변경 중 


  • idf.py show_efuse_table (각 OTP 내부구성파악)
OTP인 eFuse에 각 Table 구성과 Field name을 쉽게 파악가능하다. 

(idf4.2_py3.8_env) D:\Works\Project\>idf.py show_efuse_table  //ESP Project 내에서 실행하며, 각 Field name 파악
Executing action: show_efuse_table
Running ninja in directory d:\works\project\mod610_sw\build
Executing "ninja show_efuse_table"...
[1/1] cmd.exe /C "cd /D D:\Works\Project\mod610_sw\build\esp-idf\efus...ts/efuse/esp32/esp_efuse_table.csv -t esp32 --max_blk_len 192 --info" 
Parsing efuse CSV input file C:/Users/jhlee/esp/esp-idf/components/efuse/esp32/esp_efuse_table.csv ...
Verifying efuse table...
Max number of bits in BLK 192
Sorted efuse table:
#       field_name                      efuse_block     bit_start       bit_count  //Field name 과 Block 위치 와 Bit Start 파악
1       WR_DIS_FLASH_CRYPT_CNT          EFUSE_BLK0         2               1
2       WR_DIS_BLK1                     EFUSE_BLK0         7               1
3       WR_DIS_BLK2                     EFUSE_BLK0         8               1
4       WR_DIS_BLK3                     EFUSE_BLK0         9               1
5       RD_DIS_BLK1                     EFUSE_BLK0         16              1
6       RD_DIS_BLK2                     EFUSE_BLK0         17              1
7       RD_DIS_BLK3                     EFUSE_BLK0         18              1
8       FLASH_CRYPT_CNT                 EFUSE_BLK0         20              7
9       UART_DOWNLOAD_DIS               EFUSE_BLK0         27              1
10      MAC_FACTORY                     EFUSE_BLK0         32              8
11      MAC_FACTORY                     EFUSE_BLK0         40              8
12      MAC_FACTORY                     EFUSE_BLK0         48              8
13      MAC_FACTORY                     EFUSE_BLK0         56              8
14      MAC_FACTORY                     EFUSE_BLK0         64              8
15      MAC_FACTORY                     EFUSE_BLK0         72              8
16      MAC_FACTORY_CRC                 EFUSE_BLK0         80              8
17      CHIP_VER_DIS_APP_CPU            EFUSE_BLK0         96              1
18      CHIP_VER_DIS_BT                 EFUSE_BLK0         97              1
19      CHIP_VER_PKG                    EFUSE_BLK0        105              3
20      CHIP_CPU_FREQ_LOW               EFUSE_BLK0        108              1
21      CHIP_CPU_FREQ_RATED             EFUSE_BLK0        109              1
22      CHIP_VER_REV1                   EFUSE_BLK0        111              1
23      ADC_VREF_AND_SDIO_DREF          EFUSE_BLK0        136              6
24      XPD_SDIO_REG                    EFUSE_BLK0        142              1
25      SDIO_TIEH                       EFUSE_BLK0        143              1
26      SDIO_FORCE                      EFUSE_BLK0        144              1
27      CHIP_VER_REV2                   EFUSE_BLK0        180              1
28      ENCRYPT_CONFIG                  EFUSE_BLK0        188              4
29      CONSOLE_DEBUG_DISABLE           EFUSE_BLK0        194              1
30      ABS_DONE_0                      EFUSE_BLK0        196              1
31      DISABLE_JTAG                    EFUSE_BLK0        198              1
32      DISABLE_DL_ENCRYPT              EFUSE_BLK0        199              1
33      DISABLE_DL_DECRYPT              EFUSE_BLK0        200              1
34      DISABLE_DL_CACHE                EFUSE_BLK0        201              1
35      ENCRYPT_FLASH_KEY               EFUSE_BLK1         0              192
36      SECURE_BOOT_KEY                 EFUSE_BLK2         0              192
37      MAC_CUSTOM_CRC                  EFUSE_BLK3         0               8
38      MAC_CUSTOM                      EFUSE_BLK3         8               48
39      ADC1_TP_LOW                     EFUSE_BLK3         96              7
40      ADC1_TP_HIGH                    EFUSE_BLK3        103              9
41      ADC2_TP_LOW                     EFUSE_BLK3        112              7
42      ADC2_TP_HIGH                    EFUSE_BLK3        119              9
43      SECURE_VERSION                  EFUSE_BLK3        128              32
44      MAC_CUSTOM_VER                  EFUSE_BLK3        184              8

Used bits in efuse table:
EFUSE_BLK0
[2 2] [7 9] [16 18] [20 27] [32 87] [96 97] [105 109] [111 111] [136 144] [180 180] [188 191] [194 194] [196 196] [198 201]

EFUSE_BLK1
[0 191]

EFUSE_BLK2
[0 191]

EFUSE_BLK3
[0 55] [96 159] [184 191]

Note: Not printed ranges are free for using. (bits in EFUSE_BLK0 are reserved for Espressif)



  • espefuse.py 사용법 (OTP 제어방법 확인)
아래와 같이 기본사용법을 확인을 반드시 하도록하며, 각 명령어에 따라 사용하도록하자. 
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py  //esefuse 사용법확인 
espefuse.py v3.1-dev
usage: espefuse.py [-h] [--chip {auto,esp32,esp32s2,esp32s3beta2,esp32s3beta3,esp32c3}] [--baud BAUD] [--port PORT]
                   [--before {default_reset,no_reset,esp32r1,no_reset_no_sync}] [--debug] [--virt] [--path-efuse-file PATH_EFUSE_FILE]        
                   [--do-not-confirm]
                   {burn_efuse,read_protect_efuse,write_protect_efuse,burn_block_data,burn_bit,adc_info,dump,summary,burn_key,burn_key_digest,set_flash_voltage,burn_custom_mac,get_custom_mac}
                   ...

positional arguments:
  {burn_efuse,read_protect_efuse,write_protect_efuse,burn_block_data,burn_bit,adc_info,dump,summary,burn_key,burn_key_digest,set_flash_voltage,burn_custom_mac,get_custom_mac}
                        Run espefuse.py {command} -h for additional help
    burn_efuse          Burn the efuse with the specified name   //Feild name 기반 Write 기능,  burn_bit 와 동일 
    read_protect_efuse  Disable readback for the efuse with the specified name
    write_protect_efuse
                        Disable writing to the efuse with the specified name
    burn_block_data     Burn non-key data to EFUSE blocks. (Don't use this command to burn key data for Flash Encryption or ESP32 Secure      
                        Boot V1, as the byte order of keys is swapped (use burn_key)).
    burn_bit            Burn bit in the efuse block.   //burn_efuse 거의 동일하며, Block 과 Bit를 입력하여 Write  
    adc_info            Display information about ADC calibration data stored in efuse.
    dump                Dump raw hex values of all efuses
    summary             Print human-readable summary of efuse values
    burn_key            Burn a 256-bit key to EFUSE: BLOCK1, flash_encryption, BLOCK2, secure_boot_v1, secure_boot_v2, BLOCK3
    burn_key_digest     Parse a RSA public key and burn the digest to eFuse for use with Secure Boot V2
    set_flash_voltage   Permanently set the internal flash voltage regulator to either 1.8V, 3.3V or OFF. This means GPIO12 can be high or    
                        low at reset without changing the flash voltage.
    burn_custom_mac     Burn a 48-bit Custom MAC Address to EFUSE BLOCK3.
    get_custom_mac      Prints the Custom MAC Address.

optional arguments:
  -h, --help            show this help message and exit
  --chip {auto,esp32,esp32s2,esp32s3beta2,esp32s3beta3,esp32c3}, -c {auto,esp32,esp32s2,esp32s3beta2,esp32s3beta3,esp32c3}
                        Target chip type
  --baud BAUD, -b BAUD  Serial port baud rate used when flashing/reading
  --port PORT, -p PORT  Serial port device
  --before {default_reset,no_reset,esp32r1,no_reset_no_sync}
                        What to do before connecting to the chip
  --debug, -d           Show debugging information (loglevel=DEBUG)
  --virt                For host tests, the tool will work in the virtual mode (without connecting to a chip).
  --path-efuse-file PATH_EFUSE_FILE
                        For host tests, saves efuse memory to file.
  --do-not-confirm      Do not pause for confirmation before permanently writing efuses. Use with caution.



  • espefuse.py 사용방법 (OTP 설정값 확인용)
실제 Serial에 연결하여 각 설정 값을 확인하도록 하자 
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 summary     //OTP 설정된것 확인용 
Connecting....
Detecting chip type... ESP32
espefuse.py v3.1-dev
EFUSE_NAME (Block)                       Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
BLK3_PART_RESERVE (BLOCK0):              BLOCK3 partially served for ADC calibration data   = False R/W (0b0)
ADC_VREF (BLOCK0):                       Voltage reference calibration                      = 1114 R/W (0b00010)

Config fuses:
XPD_SDIO_FORCE (BLOCK0):                 Ignore MTDI pin (GPIO12) for VDD_SDIO on reset     = False R/W (0b0)
XPD_SDIO_REG (BLOCK0):                   If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset    = False R/W (0b0)
XPD_SDIO_TIEH (BLOCK0):                  If XPD_SDIO_FORCE & XPD_SDIO_REG                   = 1.8V R/W (0b0)
CLK8M_FREQ (BLOCK0):                     8MHz clock freq override                           = 55 R/W (0x37)
SPI_PAD_CONFIG_CLK (BLOCK0):             Override SD_CLK pad (GPIO6/SPICLK)                 = 0 R/W (0b00000)
SPI_PAD_CONFIG_Q (BLOCK0):               Override SD_DATA_0 pad (GPIO7/SPIQ)                = 0 R/W (0b00000)
SPI_PAD_CONFIG_D (BLOCK0):               Override SD_DATA_1 pad (GPIO8/SPID)                = 0 R/W (0b00000)
SPI_PAD_CONFIG_HD (BLOCK0):              Override SD_DATA_2 pad (GPIO9/SPIHD)               = 0 R/W (0b00000)
SPI_PAD_CONFIG_CS0 (BLOCK0):             Override SD_CMD pad (GPIO11/SPICS0)                = 0 R/W (0b00000)
DISABLE_SDIO_HOST (BLOCK0):              Disable SDIO host                                  = False R/W (0b0)

Efuse fuses:
WR_DIS (BLOCK0):                         Efuse write disable mask                           = 0 R/W (0x0000)
RD_DIS (BLOCK0):                         Efuse read disable mask                            = 0 R/W (0x0)
CODING_SCHEME (BLOCK0):                  Efuse variable block length scheme
   = NONE (BLK1-3 len=256 bits) R/W (0b00)
KEY_STATUS (BLOCK0):                     Usage of efuse block 3 (reserved)                  = False R/W (0b0)

Identity fuses:
MAC (BLOCK0):                            Factory MAC Address
   = c4:dd:57:71:08:08 (CRC 0x5f OK) R/W
MAC_CRC (BLOCK0):                        CRC8 for factory MAC address                       = 95 R/W (0x5f)
CHIP_VER_REV1 (BLOCK0):                  Silicon Revision 1                                 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0):                  Silicon Revision 2                                 = True R/W (0b1)
CHIP_VERSION (BLOCK0):                   Reserved for future chip versions                  = 2 R/W (0b10)
CHIP_PACKAGE (BLOCK0):                   Chip package identifier                            = 1 R/W (0b001)
MAC_VERSION (BLOCK3):                    Version of the MAC field                           = 0 R/W (0x00)

Security fuses:
FLASH_CRYPT_CNT (BLOCK0):                Flash encryption mode counter                      = 0 R/W (0b0000000)
UART_DOWNLOAD_DIS (BLOCK0):              Disable UART download mode (ESP32 rev3 only)       = False R/W (0b0)
FLASH_CRYPT_CONFIG (BLOCK0):             Flash encryption config (key tweak bits)           = 0 R/W (0x0)
CONSOLE_DEBUG_DISABLE (BLOCK0):          Disable ROM BASIC interpreter fallback             = True R/W (0b1)
ABS_DONE_0 (BLOCK0):                     Secure boot V1 is enabled for bootloader image     = False R/W (0b0)
ABS_DONE_1 (BLOCK0):                     Secure boot V2 is enabled for bootloader image     = False R/W (0b0)
JTAG_DISABLE (BLOCK0):                   Disable JTAG                                       = False R/W (0b0)
DISABLE_DL_ENCRYPT (BLOCK0):             Disable flash encryption in UART bootloader        = False R/W (0b0)
DISABLE_DL_DECRYPT (BLOCK0):             Disable flash decryption in UART bootloader        = False R/W (0b0)
DISABLE_DL_CACHE (BLOCK0):               Disable flash cache in UART bootloader             = False R/W (0b0)
BLOCK1 (BLOCK1):                         Flash encryption key
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK2 (BLOCK2):                         Secure boot key
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK3 (BLOCK3):                         Variable Block 3
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
상위보다는 거의 사용하지 않겠지만, 다른 기계와 설정값 비교할때는 dump가 최고 
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 dump //OTP 설정된것 확인용 
Connecting....
Detecting chip type... ESP32
BLOCK0          (                ) [0 ] read_regs: 00000000 57710808 005fc4dd 0000a200 00000237 00100000 00000004
BLOCK1          (flash_encryption) [1 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK2          (secure_boot_v1 s) [2 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
BLOCK3          (                ) [3 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
espefuse.py v3.1-dev
만약, MAC을 사서 사용한다면 그때 설정하고 확인 
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 get_custom_mac  //기본으로 사용하므로 없음
Connecting.....
Detecting chip type... ESP32
espefuse.py v3.1-dev
Custom MAC Address is not set in the device.

  • Secure Boot 설정완료 후 OTP 설정 할 것 
SecureBoot를 완벽히 진행하려면, 나중에는 JTAG 과 UART를 막아야 하며, 이후 부터 OTA로만 진행 
  1. ESP32 의 JTAG 막기 
  2. ESP32 UART BOOT 막기 
//EfuseDefineFields
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 burn_efuse   JTAG_DISABLE 1        --before default_reset --do-not-confirm   
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 burn_efuse   UART_DOWNLOAD_DIS 1   --before default_reset --do-not-confirm   //주의: 이후 Serial로 eFUSE도 동작안됨
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 burn_efuse   CONSOLE_DEBUG_DISABLE 1

(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 burn_bit BLOCK0 198   //DISABLE_JTAG  , 상위와 동일 
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 burn_bit BLOCK0 27    //UART_DOWNLOAD_DIS
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 burn_bit BLOCK0 194   //CONSOLE_DEBUG_DISABLE

--before default_reset --do-not-confirm  반드시 사용 


(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 adc_info

(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 read_protect_efuse  BLOCK0
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 write_protect_efuse



eFUSE API를 사용할 경우 



10/13/2022

Secure Boot (ESP32/ARM) 비교 및 기본이해

1. 기본 Certificate 활용 및 암호화 이해 

일반 기본 암호화 개념부터 알고, 그 다음에 Cetificate 를 왜 사용하는지 부터 알아보도록하자.
정확히 Authentication(인증)이라고 하는게 맞을 것 같다. 

주로 많이 사용되는 것은 TLS/SSL일 것이며, 이를 이용한 HTTPS 비롯하여 다양한 네트워크 프로토콜에서 사용되어지고 있다. 
그리고, 이를 넘어 Security Boot 를 비롯하여, Android app 인증등 많은 곳에서 사용되어지는 암호화 기술이다. 


  • 각 기본용어확인 
Authentication 과 Public Key 기반의 Certificate 및 Format X.509

보통 Certificate는 X.509 Format로 저장되어지므로 상위 기본내용은 알아두도록 하자. 

  • 암호화 기본개념
암호화의 기본개념과 Cetificate 기반의 TLS 기본이해 

  • Android의 인증시스템 구조 
Android에서 App을 인증하는 방법으로 Cerficate 기반의 Singining 과 Verfication  

  • SELinux(Security-Enhanced Linux)
SELinux로  Linux에서 인증된 App 과 그렇지 못한 App을 구분하여 실행하는 구조이다. (상위 Android 와 비슷하다.)  
OP-TEE기능으로 구현이 되어있을 지도 모르며, Selinux 기능은 Kernel Argument로 on/off를 할 수 있는 것으로 기억하며 Kernel config도 있다. 

  • ECDSA  Key 및 Certificate 생성 및 분석 
요즘 대세인 ECSDA Cerficiate 구조 구성 및 세부분석 과 사용방법 

  • WIFI-WPA 인증(Authentication)
WIFI의 EAP methods에서도 사용되어지며, 이부분은 Layer 2부터 같이 동작되어지며, WIFI기본 동작으로 알고 있어야 한다. 


1.1 PKCS11 와 HW Module  

내가 PKCS11를 처음 접한 것은 KCMVP를 다루면서 관련 인증서들을 분석하며 알게되면서 부터일 것 같다.
 
일단 PKCS11는 HSMs/TPM/KCMVP/CMVP/SmartCard/uSIM 등에서 주로 HW 와 함께 사용되는 기술이라고 생각되면 될 꺼 같다. 

쉬운 예를들면, 특정 HW모듈에 PKCS11 Interface기반으로 인증서를 넣어 못 건들게 하고 이 기반으로 TLS 방식으로 암호화를 하는 것이다. 
대표적으로 쉽게 이해가능한게 TPM일 것 같다. 요즘 대부분 컴퓨터에 설치되어있으니까. 

이외에도 CMVP라고 HW모듈기반으로 TLS/DTLS 통신하는 것이 있으며, 다양한 것이 있으므로 너무 암호화를 한정적으로만  생각할 수가 없을 것 같다. 
이 내용을 Secure Boot에 다루는 이유는 이 기반으로 Booting에도 사용되어지기 때문이며, 이외 다양하게 사용되어진다. 

  • PKCS(Public-Key Cryptography Standard) 11 관련내용
PKCS11의 경우 Token or Key를 저장하는 구조이며, 이에 관련 된 정보들은 아래 
  

2. ARM HW 암호화 구성   

ARM의 경우, TrunstZone과 다양한 HW 암호화를  제공하고 있어, ARM을 기반으로 보안기능을 제공하고 있으며, 
이 기능기반으로 Secure Boot로 뿐만 아니라 다양한 암호화 기능을 사용가능하다. 
암호화된 App 실행를 비롯하여, TLS/SSL 를 비롯하여 다양하게 사용되어진다.  

암호화에 대해서 너무 한정적으로 생각하지 말도록하자. 


2.1 ARM의 TrustZone 과 TEE 기능이해 

ARM의 경우는 TEE(Trust Execution Environment)REE(Rich Execution Environment)로 ARM 내부에서 분리되어 실행되어진다. 
이는 기본으로 MMU를 기반으로 Protection을 진행하여 제어하는 방법이 필수 일 것 같다. 

  1. TEE(Trust Execution Environment) : ARM의 TrustZone을 이용하여 실행되는 환경구조 
  2. REE(Rich Execution Environment): ARM의 TrustZone을 사용안하는 환경구조 


  • ARM의 TrustZone 과 MMU 사용  
다중 Core를 사용하다보니, MMU기반으로 분리를 하는게 쉽지는 않는 것으로 보인다. 


  • ARM에서 PKCS11 기반으로 OP-TEE 사용
NXP의 i.MX8의 Secure Boot 

  • OP-TEE를 이용하여 Secure Application 실행 
TA(Truested Application)

PKCS#11 과 OP-TEE의 i.MX8 관련내용(PCKS#11 TA)

PKCS#11 과 OP-TEE 의 IoT 관련내용 

OP-TEE 사용법과 이해  


  • ARM TrustZone
ARM에서 제공하는 HW적은 암호화 기능이며, 이를 확장하여 사용하는 것 TEE/REE    

  • Uboot의 TEE(Trusted Execution Environment) 
TEE(Trusted Execution Environment) 이며, 즉 Secure Boot를 비롯하여 Secure App, 다양한 암호화를 ARM HW부터 제공한다. 
Linux Command인 TEE 명령어와 혼동하지 말도록하자 

  • Uboot의 TEE(Trusted Execution Environment) 와 OP-TEE(Open Portable TEE) 예제 
Uboot에서 TEE를 설정하여 Secure Boot를 진행가능하며, OP-TEE도 설정가능 

  • Yocto에서는 OP-TEE(Open Portable TEE) 제공
이를 이용하여 Secure Boot를 비롯하여 인증된 App을 실행가능 한걸로 기억하며, 유사기술이 SELinux인걸로 기억한다. 

기존에 알고있는것을 다 정리 할 수 없을 것 같아 상위 정도로만, ARM 관련사항 정리를 마무리하고, 
TI Sitara or DM Series 확인을 한번 더 확인 

3. ESP32 HW 암호화

ESP32의 경우는 HW 암호화 기능과 OTP(One-Time Programmable), 즉 eFUSE를 제공하며, 다양한 암호화 기능을 제공한다.  
여기서 OTP(One-Time Programmable)이며, OTP(One-Time Password)이 가 아니므로 혼동하지 말자. 

결론적으로, ESP32도  eFUSE(One Time Programing) 이곳에서는 Secure Boot  PKCS11 기반의 Secure Boot과 거의 동일한 걸로 보이며, 
ARM처럼 HW 암호화기능 있어, 거의 유사하게 동작가능하며, 이외 ESP32 HW 암호화 기능도 제공해주고 있다. 

ESP32를 가격이 싸다고 만만히 볼만한 MPU는 아닌것 같으며, 정말로 다양한 기능을 제공하고 있다

3.1 ESP32의 Secure Boot 

ESP32의 Secure Boot의 OTP(One Time Programing,eFUSE)기반으로 진행되는 Siging/Verfication 기술이며, 이를 ESP32에서 제공을 해준다. 
ESP32의 경우도 역시 내부적으로 HW적으로 암호화 기능을 제공해지만, ARM의 TrustZone 동작방식과는 다르며,
내부적으로 간단하게 구성하여 제공해주고 있다. 




  • OTP(One Time Programing,eFUSE)
ESP32 내부에 제공해주는 1024bit 저장장소 제공해주고 있으며, 각 256bit 씩 4개의 Block으로 관리되어 지고 있다. 
OTP(eFUSE)의 경우 0 -> 1로만 변경가능하며, 한번 1로 변경되면 변경 불가능하다. 
https://blog.espressif.com/understanding-esp32s-security-features-14483e465724


  • ESP32 의 Secure Boot 의 전체 Flow  
Reset 후 ROM에서 1st stage 인 ROM에서 Boot를 하고 OTP(eFUSE)의 설정에 따라 동작이 되어진다. 
  1. OTP(eFUSE)에 저장된 Key 값 기반으로 Flash의 BootLoader를 Load 하기 전에 Verify하고 Booting  
  2. Flash의 Bootloader는 Bootloader 처럼 App image를 Verify를 진행하여 Booting 

https://blog.espressif.com/understanding-esp32s-security-features-14483e465724

상위구조를 쉽게 설명하면, OTP(One Time Programiming, eFUSE)에는 저장소의 한계 (256bit) 때문에 Hash(Token) 이용하여 한 번 더 검증하는 방식이다. 
보통 다른 곳에서는 이 Hash를 Token이라고도 많이 부르기도 한다. 


  • SecureBoot 의 BootLoader 구성 과 OTP(eFuse) 
  1. Bootloader Image:  Flash 에서 실행가능한 일반적인 image 이며, 일반부팅은 이것만 필요 
  2. RSA Signature:  Certificate의 Signature 처럼 상위 Image의 RSA3072기반으로 Private Key 로 생성 
  3. RSA 3072 Public Key: 상위 RSA Signature를 확인하기 위해서 Public Key가 필요 
  4. OTP(eFUSE): 저장된 Key의 Hash(SHA-256)로 RSA 3072 Public Key가 Verify 검증 


  • Bootloader 를 실행하기 전에 아래의 동작을 수행 
  1. OTP(eFuse)의 Hash를 이용하여 RSA 3072 Public Key가 맞는지 확인(Public Key Verfication)
  2. RSA 3072 Public Key를 이용하여 RSA Signature를 확인가능  
  3. Bootloader 실행 (RSA Signature는 이미 검증된 것임)

https://blog.espressif.com/understanding-esp32s-security-features-14483e465724


  • Flash 의 App Image의 기본구성 
상위와 동일한 구조 구조 이므로 생략 

  • Flash Encryption 
Secure Boot 기능을 넘어  Flash 저장된 정보를 ESP32 HW적으로 AES Key기반으로 Decrytion을 하여 동작가능하게 하는 기능이다. 
하지만, 이 기능을 사용하면, ESP32 성능과 Flash 기반의 XiP가 어떻게 될지가 좀 의문이다. 
그림상으로는 완벽하지만, 항상 실행해보면 문제가 생기는 경험을 많이 했기때문에, 나중에 한번 해보고 말을 해야 할 것 같다. 
(특히, SRAM 문제, Cache도 SRAM에 포함되며, 설정에 따라 SRAM 사용구조가 변경)

https://blog.espressif.com/understanding-esp32s-security-features-14483e465724




ESP32-S2 Secure Boot 

11/10/2021

AWS FreeRTOS Provisiong 자료수집 및 이해

1. AWS Provisioning 관련자료 

AWS Provisiong 관련자료 수집중이며, 우선 전체 구조와 동작방식 및 관련내용 메뉴얼을 우선 숙지 후 관련내용 정리 

우선 이를 기본적으로 이해하기 위해서는 TLS를 반드시 알아야하며, ESP32에서 AWS FreeRTOS를 사용하지 않고,
FreeRTOS에서 AWS-SDK를 Porting하여 기본 테스트를 진행하였지만, 현재 사용하고 있는 곳에서는 SRAM이 부족하여 이를 사용하기가 힘들 것 같다. 
다만, 일반적인 ESP32에서는 충분히 사용가능하다. 

AWS의 Embedded SDK Components 사용법 
최근에 들어가보니, 소스가 많이 변경되어 있으며, Manual도 새로 업데이트가 되어있다.
진작에 올려놓을 것이지, 젠장 
component도 이전과 완전다르며, 가능하다면, 최신버전으로 사용하시길 


  • AWS Provisiong 용어정리 
AWS Provisioning 의 크게 X.509 CSR(Certificate Signing Request) 구분되어진다. 
CSR도 X.509의 일종이지만, X.509를 요청하여 받는 것이며, 포맷은 X.509와 거의 유사하다.
  1. Fleet Provisiong without certificates: CSR 기반으로 인증서가 없이 인증하는 방법으로 나오며 다시 2종류 분류 
  2. Provisiong with certificates: X.509를 Device에 내장하여 진행하는 것으로 다시 3종류로 분류구분  


  • Provisioning with certificates 
Device들은 Certificate와 Private Key를 가지고 있는 구조로 또 다시 각 3개의 방식으로 구분되어짐 
참고로 상위 이름은 내가 임의로 정하며 AWS에서는 별다른 용어를 사용안함 
 
  1. JITP(Just in Time Provisioning): AWS IoT Core 만 이용 
  2. JITR(Just in Time Registration):  AWS IoT Core 와 AWS Lamda 이용 
  3. MAR(Multi-Account Registration): AWS IoT Core 의 Account가 여러개 사용 

결정적으로 보면, AWS IoT Core 와 AWS Lamda를 사용 때문으로 판단
그리고 Account를 한개 혹은 멀티로 가는지로 구분  

1.1 Fleet Provisioning by Claim 

Device는 Claim cerficates 와 private key와 함께 제조되어 생산되어진다.
그리고, 이 기반으로  AWS IoT core에 접속하여 CSR로 다시 unique device certicate로 다운을 받아 인증을 받고 이를 등록 후 TLS통신시작되어진다.  

Port 8883

  • Claim-based의 문서를 보면 크게 두개로 분리
  1. Device에게 전달되기전 (CreateProvisiongTemplate를 만들고 이를 IoT Thing등록)
  2. Device에서 전달된 후, 즉 Device에서 진행할일 아래에 설명 (디바이스는 이곳만 확인)

  • Device에게 Claim Certificate 전달되기 전의 과정 및 설정  
AWS에서 설정해야 할것들이라고 보면 될것 같다. 
  1. create-provisioning-template:  template name 과 parameter 정의
  2. create-keys-and-certificate: claim certificate 와 key  active 모드 변경 
  3. create-policy: fleet provisioning 정책결정 CreateKeysandCerficate or CreateCertificateFromCsr 

  • AWS IoT 의 create-provisioning-template 설정확인
AWS IoT -> Connect -> Fleet provisioning templates 확인 
  1. Json에서 "PolicyName": "<provisioned-thing-policy>" :  아래의 이름으로 연결됨 
  • AWS IoT 의 create-policy JSON 설정확인
AWS IoT -> 보안 -> 정책 -> provisioned-thing-policy 확인 
  1. Json에서 둘중 하나로 결정 $aws/certificates/create-from-csr or $aws/certificates/create 설정


  • AWS IOT Endpoint
account-specific-prefix.iot.aws-region.amazonaws.com

  • Device에게 전달 된 후 진행될 일 (아래그림)
상위 그림을 간단히 요약하면, 처음 Claiim Certifcate 와 Key 기반으로 TLS로 MQTT로 AWS IoT를 접속하여 아래와 같이 두번의 절차를 진행 
  1. CreateKeysAndCertificate or CreateCertificateFromCsr 진행 
  2. RegisterThing진행 


https://d1.awsstatic.com/whitepapers/device-manufacturing-provisioning.pdf


  • MQTT의 TOPIC: Unique Device Certicate 와 Key Download
  1. $aws/certificates/create/json
  2. $aws/certificates/create/json/accepted
  3. $aws/certificates/create/json/rejected

MQTT CreateKeysAndCertificate
상위 TOPIC과 동일하며 Embedded C or C++ 예제는 현재없음(직접작성)

MQTT CreateCertificateFromCsr
상위 TOPIC중 create를 create-cert-csr로 변경, 예제참조가능하나 테스트 못함  

HTTP CreateKeysAndCertificate 
Fleet Provisiong는 미지원으로 파악되지만, 일반 Provisiong은 가능 (Owershiptoken이 필요)

  • MQTT 의 TOPIC : AWS Lamda 연결및  Provisiong Template
  1. $aws/provisioning-templates/{template-name}/provision/json
  2. $aws/provisioning-templates/{template-name}/provision/json/accepted
  3. $aws/provisioning-templates/{template-name}/provision/json/rejected

MQTT RegisterThing
상위 TOPIC과 동일하며, 이때 Device의 정보를 Parameter로 전달하고 Configuration 값을 받음

HTTP RegisterThing 
일반 Provisiong 에서 사용가능하나, Fleet Provisiong은 불가능 파악 (Ownership Token이 없음)

AWS MQTT API 

관련소스 Header 

PKC11의 전체구조
현재 PKC11의 필요성이 Token인데, 이 부분이 Ownership Token하고 관련이 있는지?? 


1.2 Fleet Provisioning by Trusted User

AWS IoT에 처음 접속할 때 Trusted User 경우에 사용한다고하며, 주로 End User/설치기술자가 될 때 사용한다고 한다.   
Claim 과 차이는 처음부터 CSR을 가지고 있지 않으며, Trusted User가 CreateProvisiongTemplate 함수를 이용하여 CSR와 CSR Key를 받으면, 상위 구조와 얼추 비슷하게 흘러간다. 

Claim 과 차이라고하면, CSR를 누가 갖고 있는냐고, 이기능은 AWS Lamda를 미사용 


https://d1.awsstatic.com/whitepapers/device-manufacturing-provisioning.pdf


AWS API (CreateProvisiongTemplate) HTTP로 구현 

CreateProvisiongTemplate 는 AWS CLI에서 어떻게 하는것으로 생각되어짐 


1.3 Fleet Provisiong PC기반 테스트 

  • Fleet Provisiong PC기반테스트 방법
  1. Create a provisiong temlate  (aws iot 로 진행)
  2. Create claim cirtificate and key (Claim 인증서/Key 생성)
  3. 상위 결과의 JSON에서  .certificateArn 값을 얻어옴 
  4. AWS IoT의 Policy를 claim certificate를 위해서 생성 및 이를 연결  
  5. Device에서 python code 로 fleet provision 진행 (Serial 과 Device 정보)
  6. fleet provisiong이 완료 후 이를 검증 
  7. mosquitto로 fleet provisiong 후 얻은 certificate와 key로 진행  (root.ca)


2. FreeRTOS AWS SDK Provisiong 관련자료 

  • CreateCertificateFromCsr: TOPIC도 가능하며, 예제참조 
Fleet Provisiong의 기본개념은 CSR을 이용하여 AWS IoT에게 X.509를 받아 저장 후 이를 기반으로 등록한 후 TLS통신을 하는 개념이다.  
이때 사용되어지는 것이 MQTT이며, 이를 이용하여 요청 및 인증서를 받는다. 


AWS MQTT Demo의 구성
AWS MQTT에서 내부적으로 Backoff 기능을 사용되는 것으로 파악(Back Off가 무엇인지?)
한글문서는 오타가 너무 많음(재미있는 것은 현재 ESP32는 MQTT QoS 1기반 TLS 이지만 아래는 QoS2 사용)  

AWS IoT Device SDK C 관련문서: Fleet Provisioning
현재 이상한 것은 이 관련된 함수는 AWS FreeRTOS에는 없는 것으로 파악 (API가 서로 다른 것으로 파악되며 최신꺼에도 아래 함수가 없어짐?? 선택?)
CSR기반으로 하는 인증 찾음 (관련 한글설명도 나옴)

CSR기반으로 하는 인증의 전체구조 
현재 Provisiong Library 없어진것으로 파악, 주의해야 함 (참조만 해야할 것 같음)


AWS MQTT Fleet Provisioning
MQTT Provisiong을 하는데, CSR을 사용하는 것으로 추측 

AWS FreeRTOS  관련문서 
AWS FreeRTOS와 상위 IoT Device의 소스에서 사용되는 함수 다르며, 이것도 글을 읽어보면 CSR기반??

AWS FreeRTOS Build 및 개발환경 (ESP32)
ESP-IDF가 전부 4.2기준으로 작성되며 이 부분 확인 

Fleet Provisioning 관련 정보
글을 읽다보면, CSR을 이용하여 동작이 되는 것 같으며, 이유는 ROM size를 줄이기 위해서 X.509를 사용하지 않는 것으로 보이는데, 전의 KCMVP 와 좀 다른 구조?
어째든 ECDSA 기반으로 구성되는 것으로 보임 

AWS 개발자 Guide로 CA 및 인증서 등록방법 추후 알아야 할 거 같음 

AWS CLI
GCP와 구조가 비슷한 것으로 보이며, 일단 이거 사용법은 나중에 알아야 할 거 같음



2.2 PKCS#11 의 이해

PKCS는 공개키 암호화 표준으로 AWS IoT에서 PKCS#11을 사용하며, 이곳에 Ceritificate를 보관하여 동작하는 구조이다.

PKCS(Public Key Cryptography Standards)

PKCS#11 (Cryptographic Token Interface Base Specification)
문서를 읽어보면, Smart Card, TPM(Trusted Platform Module), HSM(Hardware Security Module)에 사용되어진다고 하며,
Secure Key를 Storage에 저장하는 역할이라고 하며,
표준은 두 군데에서 진행하며 주로 보면 OASIS가 주체적으로 하는 것으로 보임



AWS corePKCS11 
AWS에서는 처음 PKCS11 Sessiong을 생성한 후 Cerficate와 Key를 PKCS11를 이용하여 RSA 혹은 ECDSA 방식 corePKCS11를 이용하여 Provising을 Flash Storage 저장한다.
이 PKCS11으로 저장된 Cerficate와 Key의 기반으로 Session을 만들어 TLS를 사용하여 접속진행
현재 ESP32 OpenSSL이 아닌 mbedTLS를 사용하는 구조임

xInitializePkcs11Session
SlotList를 가져오고, PKCS11 Login

Certificate 와 Key를 PKCS11으로 Provisiong 진행
provisionCertificate

provisionPrivateKey

Mbedtls_Pkcs11_Connect
Mbedtls_Pkcs11_Recv
Mbedtls_Pkcs11_Send


소스보면, Fleet Provisiong을 해보면 내부에 DER형식으로 Template으로 Certificate와 Key를 별도생성하는데,
이 API를 이용하며 RSA/ECDSA 방식으로 각 Certificate와 Private Key를 저장한 후 PKCS11 Session 기반의 TLS을 사용하는데,
일반적인 TLS와는 다른 방식으로 보인다.
현재로 보면 AWS에서 PKCS11는 필요할 것으로 보임

PKCS11
관련 한글자료


2.3 FreeRTOS의 AWS Provisiong 관련소스

현재 Embedded 용으로 파악되는 것은 아래와 같이 Provisiong을 위해서 두개의 OpenSource 이며
관련내용은 아래의 링크를 참조해서 파악하자.

  • AMAZON FREERTOS (AWS FreeRTOS)
Amazon에서 FreeRTOS기반으로 SDK가 포함되어져 만들었으며, Provisiong을 어떻게하는지 파악을 못함

  • AWS IoT Device SDK 관련소스 (Version에따라 구조가 다름)
AWS 에서 IoT를 위한 SDK로 MQTT는 QoS2 기반으로 TLS통신하는 것으로 파악되며, 현재 ESP32의 MQTT는 지원불가능??(ESP QoS1까지만 지원)
WSS로 사용할 경우에도 RootCA 설정하는 곳이 없음 

AWS IoT Device SDK 문서 

  • AWS Provisioning Python로 PC 테스트 용 (AWS CLI 필요)
PC에서 가장 손쉽게 테스트 하는 방법으로 상위 PC 테스트 Manual에서 aws cli 와 함께 진행

1/10/2021

SELinux (Security-Enhanced Linux) 자료조사 및 정리

1. SELinux (Security-Enhanced Linux) 이해 

SELinux는 보안강화로 문제가 있는 Application들로 부터 이를 보호하기 위해서 생겨났다고 한다. 
아래와 같이 Linux Kernel의 Security Module은 Mandatory Access Control (MAC)를 지원하며, 
한마디로 필수적인 접근권한접근을 Kernel 단에서 부터 이를 실행한다. 

https://www.ni.com/ko-kr/support/documentation/supplemental/15/selinux---addressing-access-control-security-in-labview-rio-devi.html

상위과 같이 User Process  매번 Linux Kernel에게 접근권한을 허락(Yes or No)을 받아 접근하는 방식이다. 
이는 Android에서도 쉽게 볼수 있는 구조이며, 특정 Resource or File에 접근권한 외부로부터 보호할수가 있다.  


물론 SELinux 를 사용하더라도 이기능을 ON/OFF 처럼 할수있다.
  1. Enforcing : SELinux Policy에 적용하여 접근권한제어 행사  
  2. Permissive: SELinux는 접근권한제어는 하지는 않지만, warnning/debug 표시됨 
이외 disabled 비활성화가 존재 (아예사용안함)

Enforcing의 경우 SELinux Policy를 반드시 확인 

SElinux-Addressing Access Control Security in Labview
NI(National Instrument)의 Labview에서 RIO Devices 의 SELInux 관련내용 


  • SELinux의 Policy이해 
Linux User는 SELinux ID or SELinux User로 Mapping되어 동작되어진다. 






  1. Linux User 
  2. SELinux ID or SELinux User 
  3. SELinux Role
  4. SELinux Domain or SELinux Type 

  https://en.wikipedia.org/wiki/Security-Enhanced_Linux


1.1 SELinux 기본동작방식 

DAC(Discretionary Access Control) : 일반적인 Linux의 권한 접근방식
MAC(Mandatory Access Control): SELinux 기반으로 Policy에 의한 접근방식

DAC vs MAC

  • 일반 Linux DAC 동작방식 
Process ( User: swift / Group: users(media,video)가 File (User:root / Group:root) 에 접근은 아래와 같이 한다.  



DAC(Discretionary Access Control)

  • SELinux MAC 동작방식 
SELinux를 사용할 경우 Linux Kernel에서 Policy Rules에 맞게 허락을 받고 SELinux context 가 Process에 추가되어 사용할 Target context 에 접근한다. 
하지만, Policy Rules를 보면 현재 Process는 File에 접근할 권한이 없다. 



MAC(Mandatory Access Control)



  • SELinux의 Context 분석 
  1. Target 의 Context  구조 
  2. Process 의 Security Context  구조



중요한것을 설정시 서로 양쪽의 SELinux Type 기준으로 설정하며, SELinux의 Sensitivity 도 설정가능 


  • SELinux의 Sensitivity 의 Multi-Category Security (MCS) 
Sensitivity 설정방법 
user_r:user_r:user_t:s0 
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
#
#                          s0           부터     s0:c0.c5 까지 범위설정 (c는 category 약어)
#
#system_u:system_r:httpd_t:s0           -        s0:c0.c5
#                          ▼                     ▼
#                  Low security level,    High security level, also
#                  associated with no     associated with compartments
#                  compartments.          c0, c1, c2, c3, c4 and c5.

Sensitivity 확인방법 
$ semanage user -l  //SELinux User 와 Roles 확인 
SELinux User    SELinux Roles
  
root            staff_r sysadm_r
staff_u         staff_r sysadm_r
sysadm_u        sysadm_r
system_u        system_r
unconfined_u    unconfined_r
user_u          user_r

$ semanage user -l  //Sensitivity인 MCS의 Level 과 Range  c0.c1023 는 c0 부터 c1023까지   
                Labeling   MLS/       MLS/                          
SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles
  
root            sysadm     s0         s0-s0:c0.c1023                 staff_r sysadm_r
staff_u         staff      s0         s0-s0:c0.c1023                 staff_r sysadm_r
sysadm_u        sysadm     s0         s0-s0:c0.c1023                 sysadm_r
system_u        user       s0         s0-s0:c0.c1023                 system_r
unconfined_u    unconfined s0         s0-s0:c0.c1023                 unconfined_r
user_u          user       s0         s0                             user_r  



  • Type enforcement 
Process의 Context가 Target Context를 실행하기 위해서는 아래와 같은 Type enforcement 로 양쪽의 Type를 추가 하고 Class를 File하고 실행권한  추가한다.
그러면, 상위 SELinux는 실행이 가능해진다.  

      allow  type(process)  type(target) : class { }

allow user_t lib_t : file { execute };

1.2  SELinux 의 class 와 permission확인 

class는 일반 file 부터 다양한 종류의 device file 비롯하여 socket 부터 다양하게 class를 분리를 해놓았으며, 이 권한을 주는 것이므로
아래와 같이 접근할 경우 class 와 permission을 반드시 확인하자. 

  • General SELinux 
$ ls /sys/fs/selinux/class   //상위에서 정의한 class file 확인 (Linux)
appletalk_socket  db_procedure  file            netlink_audit_socket           node           socket              x_cursor     x_screen
association       db_schema     filesystem      netlink_dnrt_socket            nscd           sock_file           x_device     x_selection
blk_file          db_sequence   ipc             netlink_firewall_socket        packet         system              x_drawable   x_server
capability        db_table      kernel_service  netlink_ip6fw_socket           packet_socket  tcp_socket          x_event      x_synthetic_event
capability2       db_tuple      key             netlink_kobject_uevent_socket  passwd         tun_socket          x_extension
chr_file          dbus          key_socket      netlink_nflog_socket           peer           udp_socket          x_font
context           db_view       lnk_file        netlink_route_socket           process        unix_dgram_socket   x_gc
db_blob           dccp_socket   memprotect      netlink_selinux_socket         rawip_socket   unix_stream_socket  x_keyboard
db_column         dir           msg             netlink_socket                 security       x_application_data  x_pointer
db_database       fd            msgq            netlink_tcpdiag_socket         sem            x_client            x_property
db_language       fifo_file     netif           netlink_xfrm_socket            shm            x_colormap          x_resource

$ ls /sys/fs/selinux/class/file/perms/    //class file permission 기능 확인 
append      execmod           getattr  lock     quotaon      relabelto  swapon
create      execute           ioctl    mounton  read         rename     unlink
entrypoint  execute_no_trans  link     open     relabelfrom  setattr    write

  • Android SELinux
$ ls /sys/fs/selinux/class  //상위에서 정의한 class file 확인 (Android)
alg_socket         isdn_socket                   packet
appletalk_socket   iucv_socket                   packet_socket
association        kcm_socket                    peer
atmpvc_socket      kernel_service                phonet_socket
atmsvc_socket      key                           pppox_socket
ax25_socket        key_socket                    process
binder             keystore_key                  process2
blk_file           llc_socket                    property_service
bluetooth_socket   lnk_file                      qipcrtr_socket
bpf                memprotect                    rawip_socket
caif_socket        msg                           rds_socket
can_socket         msgq                          rose_socket
cap2_userns        netif                         rxrpc_socket
cap_userns         netlink_audit_socket          sctp_socket
capability         netlink_connector_socket      security
capability2        netlink_crypto_socket         sem
chr_file           netlink_dnrt_socket           service_manager
dccp_socket        netlink_fib_lookup_socket     shm
decnet_socket      netlink_generic_socket        smc_socket
dir                netlink_iscsi_socket          sock_file
drmservice         netlink_kobject_uevent_socket socket
fd                 netlink_netfilter_socket      system
fifo_file          netlink_nflog_socket          tcp_socket
file               netlink_rdma_socket           tipc_socket
filesystem         netlink_route_socket          tun_socket
hwservice_manager  netlink_scsitransport_socket  udp_socket
icmp_socket        netlink_selinux_socket        unix_dgram_socket
ieee802154_socket  netlink_socket                unix_stream_socket
infiniband_endport netlink_tcpdiag_socket        vsock_socket
infiniband_pkey    netlink_xfrm_socket           x25_socket
ipc                netrom_socket                 xdp_socket
ipx_socket         nfc_socket
irda_socket        node
db_language       fifo_file     netif           netlink_xfrm_socket            shm            x_colormap          x_resource

$ ls /sys/fs/selinux/class/file/perms/       //class file permission 기능 확인 
append       execute_no_trans mounton     rename      watch_sb
audit_access getattr          open        setattr     watch_with_perm
create       ioctl            quotaon     unlink      write
entrypoint   link             read        watch
execmod      lock             relabelfrom watch_mount
execute      map              relabelto   watch_reads


2. SELinux 의 Access Control 방법 

위에서 SELinux MAC 동작 방식을 봤지만 SELinux에서 Acess Control 하는 방법 아래로 구분되는 것 같다. 

  1. Type Enforcement (TE) : 가장 처음적용되는 기능 
  2. Role-Based Access Control (RBAC): 기본으로 사용하지 않는다고 함
  3. Multi-Level Security (MLS) : 상위에서 Sensitivity 에서 설정
  4. Multi-Category Security(MCS): MLS의 확장으로 



2.1 SELinux 에러 Message 분석 


avc:  denied  { read write } for  pid=1876 comm="syslogd" name="xconsole" dev=tmpfs ino=5510 scontext=system_u:system_r:syslogd_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=fifo_file permissive=1 
상위 에러는 SELinux Policy에 따라 read , write 접근이 되지 않았아 발생한 에러 
  1. scontext: process의 context
  2. tcontext: target의 context
  3. tclass: target class
  4. permissive: 1은 permissive 상태이므로 접근은 가능하지만 warning/debug 발생 




SElinux 부분 별도정리 필요 
Android App에서 권한문제로 인하여 이 관련부분을 알아보게됨 







Android SELinux 관련부분 수정방법 
*.te 생성방법 
  1. system/sepolicy/public
  2. system/sepolicy/private
  3. system/sepolicy/vendor
  4. device/manufacturer/device-name/sepolicy

  1. genfs_contexts
  2. file_contexts
  3. *.te


  • SELinux 빌드 
system/sepolicy/Android.mk

 //sepolicy 문제 , 
https://kodejava.org/how-do-i-use-datainputstream-and-dataoutputstream/
https://jung-max.github.io/2019/09/02/Android-NDK%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%84%9C-kernel%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0/

[  368.428751] type=1400 audit(1610446043.380:38): avc: denied { write } for comm="sh" name="duty_cycle" dev="sysfs" ino=37608 scontext=u:r:untrusted_app:s0:c101,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0 app=com.example.testjeonghun
[  368.452747] type=1400 audit(1610446056.140:39): avc: denied { write } for comm="sh" name="duty_cycle" dev="sysfs" ino=37592 scontext=u:r:untrusted_app:s0:c101,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0 app=com.example.testjeonghun
[  368.476177] type=1400 audit(1610446056.140:39): avc: denied { write } for comm="sh" name="duty_cycle" dev="sysfs" ino=37592 scontext=u:r:untrusted_app:s0:c101,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0 app=com.example.testjeonghun
[  368.500078] type=1400 audit(1610446056.140:40): avc: denied { write } for comm="sh" name="duty_cycle" dev="sysfs" ino=37608 scontext=u:r:untrusted_app:s0:c101,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0 app=com.example.testjeonghun


I/om.example.beep: type=1400 audit(0.0:56): avc: denied { write } for name="duty_cycle" dev="sysfs" ino=37592 scontext=u:r:untrusted_app:s0:c99,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 app=com.example.beep
I/om.example.beep: type=1400 audit(0.0:57): avc: denied { open } for path="/sys/devices/platform/bus@5d000000/5d010000.pwm/pwm/pwmchip0/pwm0/duty_cycle" dev="sysfs" ino=37592 scontext=u:r:untrusted_app:s0:c99,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 app=com.example.beep


//분석 
https://source.android.com/security/selinux/validate

//JNI
https://www.programmersought.com/article/5477408309/
https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html#zz-2.1


https://android.googlesource.com/platform/external/sepolicy/+/57531cacb40682be4b1189c721fd1e7f25bf3786/untrusted_app.te

//sys filesystem 권한 
$ vi ./system/sepolicy/public/file.te
$ vi ./device/fsl/imx8q/mek_8q/sepolicy/file_contexts

$ find . -name untrusted_app*.te
./device/fsl/imx6sl/sepolicy/untrusted_app_25.te
./device/fsl/imx7d/sepolicy/untrusted_app_25.te
./device/fsl/imx6sx/sepolicy/untrusted_app_25.te
./device/fsl/imx6dq/sepolicy/untrusted_app_25.te
./device/fsl/imx7ulp/sepolicy/untrusted_app_25.te
./device/fsl/imx8m/sepolicy/untrusted_app_25.te
./device/fsl/imx8q/sepolicy/untrusted_app_25.te
./device/google/wahoo/sepolicy/private/untrusted_app_all.te
./device/linaro/poplar/sepolicy/untrusted_app_25.te
./device/linaro/poplar/sepolicy/untrusted_app.te
./device/linaro/poplar/sepolicy/untrusted_app_27.te
./system/sepolicy/private/untrusted_app_25.te
./system/sepolicy/private/untrusted_app.te
./system/sepolicy/private/untrusted_app_27.te
./system/sepolicy/private/untrusted_app_all.te
./system/sepolicy/public/untrusted_app.te
./system/sepolicy/prebuilts/api/28.0/private/untrusted_app_25.te
./system/sepolicy/prebuilts/api/28.0/private/untrusted_app.te
./system/sepolicy/prebuilts/api/28.0/private/untrusted_app_27.te
./system/sepolicy/prebuilts/api/28.0/private/untrusted_app_all.te
./system/sepolicy/prebuilts/api/28.0/public/untrusted_app.te
./system/sepolicy/prebuilts/api/26.0/private/untrusted_app_25.te
./system/sepolicy/prebuilts/api/26.0/private/untrusted_app.te
./system/sepolicy/prebuilts/api/26.0/private/untrusted_app_all.te
./system/sepolicy/prebuilts/api/26.0/public/untrusted_app_25.te
./system/sepolicy/prebuilts/api/26.0/public/untrusted_app.te
./system/sepolicy/prebuilts/api/27.0/private/untrusted_app_25.te
./system/sepolicy/prebuilts/api/27.0/private/untrusted_app.te
./system/sepolicy/prebuilts/api/27.0/private/untrusted_app_all.te
./system/sepolicy/prebuilts/api/27.0/public/untrusted_app_25.te
./system/sepolicy/prebuilts/api/27.0/public/untrusted_app.te
./system/sepolicy/prebuilts/api/29.0/private/untrusted_app_25.te
./system/sepolicy/prebuilts/api/29.0/private/untrusted_app.te
./system/sepolicy/prebuilts/api/29.0/private/untrusted_app_27.te
./system/sepolicy/prebuilts/api/29.0/private/untrusted_app_all.te
./system/sepolicy/prebuilts/api/29.0/public/untrusted_app.te

//일반적인 Android 앱 
https://source.android.com/security/selinux/concepts
http://shincdevnote.blogspot.com/2017/04/se-for-android.html

//이것을 고치면 문제 발생 (app_neverallows.te 같이 수정해야함)
$ vi system/sepolicy/prebuilts/api/29.0/public/untrusted_app.te
$ vi ./system/sepolicy/public/untrusted_app.te
type untrusted_app, domain;
type untrusted_app_27, domain;
type untrusted_app_25, domain;

# 상위 untrusted_app domain이 선언되었음 
# sysfs 허용 sysfs domain 허용 이 부분은 file_contexts 에 각 도메인 선언 
allow untrusted_app sysfs:file rw_file_perms;


$ cat ./system/sepolicy/private/untrusted_app.te
typeattribute untrusted_app coredomain;

app_domain(untrusted_app)
untrusted_app_domain(untrusted_app)
net_domain(untrusted_app)
bluetooth_domain(untrusted_app)


$ cat ./device/fsl/imx8q/mek_8q/sepolicy/genfs_contexts
genfscon nfs / u:object_r:rootfs:s0
genfscon fuseblk / u:object_r:vfat:s0
genfscon sysfs /class/typec                                             u:object_r:sysfs_usb_c:s0
genfscon sysfs /devices/virtual/power_supply/usb                  u:object_r:sysfs_batteryinfo:s0
genfscon sysfs /devices/virtual/power_supply/battery              u:object_r:sysfs_batteryinfo:s0
genfscon sysfs /devices/platform/rtc/rtc/rtc0/hctosys             u:object_r:sysfs_rtc:s0
genfscon sysfs /devices/platform/scu/scu:rtc/rtc/rtc0/hctosys     u:object_r:sysfs_rtc:s0
genfscon sysfs /devices/platform/sound/extcon                     u:object_r:sysfs_extcon:s0
genfscon sysfs /devices/platform/sound-wm8960/extcon              u:object_r:sysfs_extcon:s0
genfscon sysfs /devices/platform/bus@56260000/56268000.hdmi/extcon      u:object_r:sysfs_extcon:s0
genfscon debugfs /dma_buf u:object_r:debugfs_dma:s0
genfscon debugfs /sync/sw_sync u:object_r:debugfs_sw_sync:s0
genfscon sysfs /devices/soc0   u:object_r:sysfs_soc:s0

#mek_8q ethernet
genfscon sysfs /devices/platform/bus@5b000000/5b040000.ethernet/net  u:object_r:sysfs_net:s0
#mek_8qm wifi
genfscon sysfs /devices/platform/bus@5f000000/5f000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/net u:object_r:sysfs_net:s0
#mek_8qxp wifi
genfscon sysfs /devices/platform/bus@5f000000/5f010000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/net u:object_r:sysfs_net:s0
genfscon binder /binder u:object_r:binder_device:s0
genfscon binder /hwbinder u:object_r:hwbinder_device:s0
genfscon binder /vndbinder u:object_r:vndbinder_device:s0
genfscon binder /binder_logs u:object_r:binderfs_logs:s0
genfscon binder /binder_logs/proc u:object_r:binderfs_logs_proc:s0
genfscon binder / u:object_r:binderfs:s0

$ ls ./device/fsl/imx8q/sepolicy/
adbd.te                           hal_composer.te                   init-insmod-sh.te                 recovery.te
audioserver.te                    hal_drm_clearkey.te               init.te                           sensors.te
bluetooth.te                      hal_drm_default.te                installd.te                       shell.te
bootanim.te                       hal_drm_widevine.te               install_recovery.te               surfaceflinger.te
bootstat.te                       hal_dumpstate_impl.te             kernel.te                         system_app.te
cameraserver.te                   hal_graphics_composer_default.te  logd.te                           system_server.te
device.te                         hal_health_default.te             mediacodec.te                     tee.te
dnsmasq.te                        hal_light_default.te              mediaextractor.te                 toolbox.te
domain.te                         hal_neuralnetworks_imx.te         mediaprovider.te                  untrusted_app_25.te
dumpstate.te                      hal_oemlock.te                    mediaserver.te                    update_engine_common.te
ephemeral_app.te                  hal_power_default.te              mediaswcodec.te                   update_engine.te
fastbootd.te                      hal_sensors_default.te            modprobe.te                       vendor_init.te
file_contexts                     hal_thermal_default.te            netd.te                           vndservicemanager.te
file.te                           hal_usb_default.te                platform_app.te                   vold_prepare_subdirs.te
genfs_contexts                    hal_usb_impl.te                   priv_app.te                       vold.te
hal_bluetooth_default.te          hal_wifi_default.te               proc_net.te                       webview_zygote.te
hal_bootctl_default.te            hal_wifi_supplicant_default.te    profman.te                        wificond.te
hal_camera_default.te             healthd.te                        property_contexts                 zygote.te
hal_cas_default.te                hwservice_contexts                property.te

$ ls ./device/fsl/imx8q/mek_8q/sepolicy
file_contexts  genfs_contexts

https://source.android.com/security/selinux/device-policy
https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#139

$ cat ./device/fsl/imx8q/mek_8q/sepolicy/file_contexts
/dev/mxc_asrc                   u:object_r:audio_device:s0
/dev/mxc_hdmi                   u:object_r:video_device:s0
/dev/mxc_hantro                 u:object_r:video_device:s0
/dev/mxc_hantro_h1              u:object_r:video_device:s0
/dev/mxc_vpu_malone             u:object_r:video_device:s0
/dev/mxc_hifi4                  u:object_r:audio_device:s0
/dev/galcore                    u:object_r:gpu_device:s0
/dev/imxdpu                     u:object_r:gpu_device:s0
/dev/caam_kb                    u:object_r:caam_device:s0
/dev/dri                        u:object_r:gpu_device:s0
/dev/dri/card0                  u:object_r:graphics_device:s0
/dev/dri/card1                  u:object_r:graphics_device:s0
/dev/dri/card2                  u:object_r:graphics_device:s0
/dev/dri/controlD64             u:object_r:graphics_device:s0
/dev/dri/controlD65             u:object_r:graphics_device:s0
/dev/dri/renderD128             u:object_r:gpu_device:s0
/dev/dri/renderD129             u:object_r:gpu_device:s0
/vendor/bin/hw/android\.hardware\.usb@1\.1-service.imx             u:object_r:hal_usb_impl_exec:s0
/dev/diag                       u:object_r:diag_device:s0
/vendor/app(/.*)?               u:object_r:same_process_hal_file:s0
/data/vendor/ss(/.*)?           u:object_r:tee_data_file:s0
/data/vendor/.opencl-cache(/.*)?       u:object_r:opencl_cache_file:s0

###############################################
# same-process HAL files and their dependencies
#
/vendor/lib(64)?/hw/gralloc\.imx\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libfsldisplay\.so          u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/nxp.hardware.display@1.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libedid\.so                u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libdrm_android\.so         u:object_r:same_process_hal_file:s0

/vendor/lib(64)?/libGLSLC\.so               u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libVSC\.so                 u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libGAL\.so                 u:object_r:same_process_hal_file:s0

/vendor/lib(64)?/hw/vulkan\.imx\.so        u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/hw/gralloc_viv\.imx\.so   u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libdrm_vivante\.so         u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libvulkan_VIVANTE\.so      u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libSPIRV_viv\.so           u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libCLC\.so                 u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libLLVM_viv\.so            u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libOpenCL\.so              u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libopencl-2d\.so           u:object_r:same_process_hal_file:s0

#early_init_sh service
/vendor/bin/init\.insmod\.sh                u:object_r:init-insmod-sh_exec:s0
/vendor/etc/early\.init\.cfg                u:object_r:init-insmod-sh_exec:s0
/vendor/etc/setup\.core\.cfg                u:object_r:init-insmod-sh_exec:s0
/vendor/etc/setup\.main\.cfg                u:object_r:init-insmod-sh_exec:s0

/vendor/lib(64)?/lib_aac_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_amr_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_asf_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_avi_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_dsf_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_flac_parser_arm11_elinux\.3\.0\.so      u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_flv_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_mkv_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_mp3_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_mp3_parser_v2_arm11_elinux\.so          u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_mp4_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_mpg2_parser_arm11_elinux\.3\.0\.so      u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_ogg_parser_arm11_elinux\.3\.0\.so       u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/lib_rm_parser_arm11_elinux\.3\.0\.so        u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/extractors/libimxextractor\.so              u:object_r:same_process_hal_file:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.keymaster@3\.0-service.trusty      u:object_r:hal_keymaster_default_exec:s0

# trusty ipc target
/dev/trusty-ipc-dev0        u:object_r:tee_device:s0

/vendor/bin/hw/android\.hardware\.health@2\.0-service.imx          u:object_r:hal_health_default_exec:s0

/vendor/bin/hw/android\.hardware\.power@1\.3-service\.imx  u:object_r:hal_power_default_exec:s0
# mmc rpmb
/dev/mmcblk0rpmb      u:object_r:mmc_rpmb_char_device:s0

# secure os storage
/vendor/bin/storageproxyd   u:object_r:tee_exec:s0

/vendor/bin/hw/android\.hardware\.drm@1\.2-service\.widevine u:object_r:hal_drm_widevine_exec:s0
/vendor/bin/hw/android\.hardware\.drm@1\.1-service\.clearkey u:object_r:hal_drm_clearkey_exec:s0
/vendor/bin/hw/android\.hardware\.drm@1\.2-service\.clearkey u:object_r:hal_drm_clearkey_exec:s0
/data/vendor/mediadrm(/.*)? u:object_r:mediadrm_vendor_data_file:s0
/vendor/bin/hw/android\.hardware\.dumpstate@1\.0-service\.imx      u:object_r:hal_dumpstate_impl_exec:s0
/dev/cpu_dma_latency u:object_r:latency_device:s0
/vendor/bin/hw/android\.hardware\.oemlock@1\.0-service\.imx      u:object_r:hal_oemlock_impl_exec:s0
/vendor/bin/hw/android\.hardware\.boot@1\.0-service\.imx      u:object_r:hal_bootctl_default_exec:s0


 http://shincdevnote.blogspot.com/2017/04/se-for-android.html
https://android.googlesource.com/platform/system/sepolicy/+/nougat-dr1-release/file_contexts
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/deployment_guide/sec-sel-building-policy-module
https://community.nxp.com/t5/i-MX-Processors/How-to-access-serial-port-from-Android-MM-application/m-p/600424
https://wenchiching.wordpress.com/2016/12/05/how-to-change-process-domain-from-untrusted_app-to-system_app/
https://jung-max.github.io/2019/09/16/Android-SEAndroid%EC%A0%81%EC%9A%A9/

$ vi ./device/fsl/imx8q/sepolicy/system_app.te
...
allow system_app sysfs:file { open read write };


$ vi ./device/fsl/imx8q/mek_8q/sepolicy/file_contexts  // /dev 이면 이곳에 추가 
....
# pwm0
/sys/devices/platform/bus@5d000000/5d010000.pwm/pwm/pwmchip0/pwm0/duty_cycle            u:object_r:pwm0_device:s0

$ vi ./device/fsl/imx8q/mek_8q/sepolicy/genfs_contexts //
...
# pwm0
genfscon sysfs /devices/platform/bus@5d000000/5d010000.pwm/pwm/pwmchip0/pwm0/duty_cycle u:object_r:sysfs_pwm0_device:s0

새 정책파일 
https://source.android.com/security/selinux/implement


$ vi ./device/fsl/imx8q/sepolicy/device.te
type sysfs_pwm0_device, sysfs_type, fs_type;

$ vi ./device/fsl/imx8q/sepolicy/pwm.te
type sysfs_pwm0_device, sysfs_type, fs_type;

allow untrusted_app sysfs_pwm0_device:dir r_dir_perms;
allow untrusted_app sysfs_pwm0_device:file rw_file_perms;
allow untrusted_app sysfs_pwm0_device:file { read write open };



****************** app.te 와 주의 
$ vi system/sepolicy/private/app_neverallows.te  //상위를 고쳐도 app이 지켜야할 부분이므로 여기서 에러 발생 
$ vi system/sepolicy/prebuilts/api/29.0/private/app_neverallows.te
주석처리 
# Do not allow any write access to files in /sys
#neverallow all_untrusted_apps sysfs_type:file { no_w_file_perms no_x_file_perms };

# Apps may never access the default sysfs label.
#neverallow all_untrusted_apps sysfs:file no_rw_file_perms;

$ vi ./device/fsl/imx8q/sepolicy/file_contexts
$ vi ./device/fsl/imx8q/mek_8q/sepolicy/file_contexts
# pwm0
/sys/devices/platform/bus@5d000000/5d010000.pwm/pwm/pwmchip0/pwm0/duty_cycle            u:object_r:sysfs_pwm0_device:s0
/sys/devices/platform/bus@5d000000/5d020000.pwm/pwm/pwmchip1/pwm0/duty_cycle            u:object_r:sysfs_pwm1_device:s0

$ vi ./device/fsl/imx8q/sepolicy/pwm.te
type sysfs_pwm0_device, sysfs_type, fs_type;

allow untrusted_app sysfs_pwm0_device:dir r_dir_perms;
allow untrusted_app sysfs_pwm0_device:file rw_file_perms;
allow untrusted_app sysfs_pwm0_device:file { read write open };


BOARD_SEPOLICY_DIRS  확인

system_app 



이 설정 때문인지 shell에서 su 명령어가 되어 root 권한으로 실행가능하지만, vi가 없음
그래서 현재 adb shell로 연결할 방법모색
cat 으로 수정하려고 함 


보안  (dm-verity)

remount 후 소스 수정후 recovery 모드로 동작