openssl 암호화(AESGCM256)

2023. 1. 8. 10:47Security ★ Development/Cryptology

반응형

암호화

EVP_CIPHER_CTX *ctx = NULL;
uint32_t IV_LEN = 12, aad_len = 4, final_len;
uint8_t key[32], iv[12], aad[4];
uint8_t *ct, *pt = "ABCD";
uint32_t ct_len = 0, pt_len = 4, out_len = 0;

//key, iv, aad set
//각 값은 복호화때와 동일한 값 사용
//key는 서로 갖고 있어야하고 iv와 aad는 암호화한 결과와 같이 넘겨줘야함.  이때 iv, aad는 plaintext형태로 넘겨줌

ctx = (EVP_CIPHER_CTX *)EVP_CIPHER_CTX_new();
if (NULL == ctx) { return ERROR; }

//EVP_aes_128_gcm() 등 사용 가능
if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) {
    //error
    goto exit;
}

//Set IV length
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, IV_LEN, NULL)) {
    //error
    goto exit;
}

//Initialize key and iv
if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) {
    //error
    goto exit;
}

//Provide AAD
if (NULL != aad && 0 != aad_len) {
    if (!EVP_EncryptUpdate(ctx, NULL, &ct_len, aad, aad_len)) {
        //error
        goto exit;
    }
}

//Encrypt
//암호화할 데이터가 잘려서 들어오면 여러번 호출 - 대용량 암호화의 경우
if (!EVP_EncryptUpdate(ctx, ct, &ct_len, pt, pt_len)) {
    //error
    goto exit;
}

if (!EVP_EncryptFinal_ex(ctx, &ct[ct_len], &final_len)) {
    //error
    goto exit;
}

//Get auth tag
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN, &ct[ct_len + final_len])) {
    //error
    goto exit;
}

//pt_len값에 EVP_GCM_TLS_TAG_LEN, 16byte가 붙은 길이가 생성
//여기에 iv, aad 등을 더해 좀 더 긴 pt 대비 output을 상대방에게 넘겨주게됨
out_len = ct_len + final_len + EVP_GCM_TLS_TAG_LEN;

exit:
EVP_CIPHER_CTX_free(ctx);

 

 

복호화

EVP_CIPHER_CTX *ctx = NULL;
uint32_t IV_LEN = 12, aad_len = 0, fianl_len;
uint8_t key[32], iv[12], aad[4];
uint8_t *ct = XX, *pt;
uint32_t pt_len = 0, ct_len = XX,  out_len;

//key set
//iv, aad get

ctx = (EVP_CIPHER_CTX *)EVP_CIPHER_CTX_new();
if (NULL == ctx) return ERROR;

if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) {
    //error
    goto exit;
}

//Set IV length
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, IV_LEN, NULL)) {
    //error
    goto exit;
}

//Initialize key and iv
if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) {
    //error
    goto exit;
}

//Provide AAD
if (NULL != aad && 0 != aad_len) {
    if (!EVP_DecryptUpdate(ctx, NULL, &pt_len, aad, aad_len)) {
        //error
        got exit;
    }
}

//Decrypt
if (!EVP_DecryptUpdate(ctx, pt, &pt_len, ct, ct_len - EVP_GCM_TLS_TAG_LEN)) {
    //error
    goto exit;
}

//Check auth tag
uint8_t *tag = &ct[ct_len - EVP_GCM_TLS_TAG_LEN];
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag)) {
    //error
    goto exit;
}

if (!EVP_DecryptFinal_ex(ctx, &pt[pt_len], &final_len)) {
    //error
    goto exit;
}

out_len = pt_len + final_len

exit:
EVP_CIPHER_CTX_free(ctx);

 

'Security ★ Development > Cryptology' 카테고리의 다른 글

SP800-108 KDF  (0) 2023.01.16
FHMQV  (0) 2016.10.30
Cryptology 문제 2  (0) 2015.12.03
Cryptology 문제 1  (0) 2015.12.03