STM32

STM32F429 AES 암호화 모듈 사용법

임베디드 친구 2025. 2. 25. 17:08
728x90
반응형

STM32F429 AES 암호화 모듈 사용법

개요

이 글에서는 STM32F429의 AES 하드웨어 가속기를 이용해 데이터 암호화와 복호화를 수행하는 방법을 설명합니다. 특히 AES-128, AES-192, AES-256 비트 키 길이를 기반으로 ECB, CBC, CTR 모드에서의 실습을 진행하고, 문자열과 파일을 AES-256으로 암호화하는 방법을 예제로 다룹니다.

STM32CubeIDE와 HAL 라이브러리를 활용하여 구현하며, 각 모드별 차이와 주의사항을 설명합니다.


1. AES 개요

AES(Advanced Encryption Standard)는 대칭 키 기반의 블록 암호화 알고리즘으로, 주로 128비트 블록과 128/192/256비트 키를 사용합니다. AES는 보안성과 성능을 고려해 다양한 운영 모드(ECB, CBC, CTR 등)를 제공합니다.

AES 운영 모드

  • ECB (Electronic Codebook Mode):

    • 각 블록을 독립적으로 암호화.
    • 동일한 입력 블록은 동일한 출력 블록을 생성.
    • 데이터 패턴이 노출될 수 있음.
  • CBC (Cipher Block Chaining Mode):

    • 이전 블록의 암호문과 현재 블록을 XOR 후 암호화.
    • 초기화 벡터(IV)가 필요.
  • CTR (Counter Mode):

    • 블록별 카운터 값을 암호화한 후 평문과 XOR.
    • 스트림 암호화처럼 동작.

2. 프로젝트 설정

STM32CubeIDE에서 AES 기능을 활성화하려면 다음과 같이 설정합니다.

  1. CubeMX 설정:

    • Crypto 탭에서 AES를 활성화합니다.
    • MiddlewarembedTLS를 활성화할 수도 있습니다.
  2. Clock Configuration:

    • Crypto 모듈과 관련된 클럭을 활성화합니다.
  3. 라이브러리 포함:

    • stm32f4xx_hal_conf.h 파일에서 #define HAL_CRYP_MODULE_ENABLED가 활성화되어 있는지 확인합니다.
  4. 코드 생성:

    • Generate Code를 눌러 프로젝트를 생성합니다.

3. AES 모드별 실습

다음은 AES-128, AES-192, AES-256을 사용해 ECB, CBC, CTR 모드에서 데이터를 암호화하고 복호화하는 예제입니다.

3.1 ECB 모드 실습

아래는 AES-128 ECB 모드에서 데이터를 암호화하고 복호화하는 예제입니다.

#include "main.h"
#include "string.h"

#define AES_KEY_SIZE_128 16

static uint8_t plainText[] = "Hello, STM32 AES!";
static uint8_t key[AES_KEY_SIZE_128] = {
    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
    0xab, 0xf7, 0x50, 0x20, 0x7f, 0x67, 0x13, 0x6d
};
static uint8_t encrypted[32];
static uint8_t decrypted[32];

void AES_ECB_Encrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYP_Encrypt(&hcryp, plainText, sizeof(plainText), encrypted, HAL_MAX_DELAY);
    HAL_CRYP_DeInit(&hcryp);
}

void AES_ECB_Decrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYP_Decrypt(&hcryp, encrypted, sizeof(encrypted), decrypted, HAL_MAX_DELAY);
    HAL_CRYP_DeInit(&hcryp);
}

int main(void) {
    HAL_Init();
    SystemClock_Config();

    AES_ECB_Encrypt();
    AES_ECB_Decrypt();

    while (1) {}
}

설명:

  • ECB 모드에서는 키만으로 블록을 독립적으로 처리합니다.
  • 패턴이 드러날 수 있으므로 민감한 데이터 전송에는 적합하지 않습니다.

3.2 CBC 모드 실습

CBC 모드는 IV(초기화 벡터)를 필요로 합니다.

static uint8_t iv[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

void AES_CBC_Encrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYPEx_AES_Encrypt(&hcryp, plainText, sizeof(plainText), key, AES_KEY_SIZE_128, iv, encrypted);
    HAL_CRYP_DeInit(&hcryp);
}

void AES_CBC_Decrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYPEx_AES_Decrypt(&hcryp, encrypted, sizeof(encrypted), key, AES_KEY_SIZE_128, iv, decrypted);
    HAL_CRYP_DeInit(&hcryp);
}

주의사항:

  • 암호화와 복호화 시 동일한 IV를 사용해야 합니다.

3.3 CTR 모드 실습

CTR 모드는 블록을 스트림처럼 처리합니다.

static uint8_t counter[16] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
                              0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04};

void AES_CTR_Encrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYPEx_AES_Encrypt(&hcryp, plainText, sizeof(plainText), key, AES_KEY_SIZE_128, counter, encrypted);
    HAL_CRYP_DeInit(&hcryp);
}

void AES_CTR_Decrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYPEx_AES_Decrypt(&hcryp, encrypted, sizeof(encrypted), key, AES_KEY_SIZE_128, counter, decrypted);
    HAL_CRYP_DeInit(&hcryp);
}

CTR 모드는 병렬 처리와 랜덤 접근에 적합하지만, 카운터가 중복되지 않도록 주의해야 합니다.


4. AES-256을 이용한 문자열과 파일 암호화

4.1 문자열 암호화

아래는 AES-256을 이용해 문자열을 암호화하고 복호화하는 예제입니다.

#define AES_KEY_SIZE_256 32

static uint8_t key256[AES_KEY_SIZE_256] = {
    0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
    0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
    0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
    0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};

void AES256_Encrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYP_Encrypt(&hcryp, plainText, sizeof(plainText), encrypted, HAL_MAX_DELAY);
    HAL_CRYP_DeInit(&hcryp);
}

void AES256_Decrypt(void) {
    CRYP_HandleTypeDef hcryp;
    hcryp.Instance = CRYP;

    HAL_CRYP_Init(&hcryp);
    HAL_CRYP_Decrypt(&hcryp, encrypted, sizeof(encrypted), decrypted, HAL_MAX_DELAY);
    HAL_CRYP_DeInit(&hcryp);
}

4.2 파일 암호화

파일을 블록 단위로 읽어 AES-256으로 암호화하고 저장하는 방법은 다음과 같이 구현할 수 있습니다.

  1. 파일을 블록(16바이트) 단위로 읽습니다.
  2. AES-256으로 암호화한 후 새로운 파일에 저장합니다.
  3. 복호화 시 동일한 과정을 역순으로 수행합니다.
void AES256_FileEncrypt(char *inputFile, char *outputFile) {
    FILE *in = fopen(inputFile, "rb");
    FILE *out = fopen(outputFile, "wb");

    uint8_t buffer[16];
    uint8_t encrypted[16];

    while (fread(buffer, 1, 16, in)) {
        HAL_CRYP_Encrypt(&hcryp, buffer, sizeof(buffer), encrypted, HAL_MAX_DELAY);
        fwrite(encrypted, 1, 16, out);
    }

    fclose(in);
    fclose(out);
}

5. 결론

이 글에서는 STM32F429의 AES 모듈을 이용해 다양한 모드로 데이터를 암호화하고 복호화하는 방법을 살펴보았습니다. ECB, CBC, CTR 모드의 차이와 AES-256을 이용한 문자열 및 파일 암호화 방법을 실습해보았습니다.

반응형