2017-04-25 7 views
0

AES_cbc_encrypt 기능을 사용하여 키 저장소를 암호화하고 암호 해독하려고합니다. openssl 라이브러리.AES_cbc_encrypt에 대한 메모리 할당

메모리 할당에 문제가 있습니다. 적절한 방법으로 누군가에게 조언을 해줄 수 있다면 좋을 것입니다.

지금 나는 AES_cbc_encrypt가 호출 하는 동안이 내가지고있어 분할 오류을 수행하는 방법을 알아낼 수 없습니다.

또 다른 질문은 char 테이블의 메모리를 C (clean way)로 할당하는 방법입니다. 나는 이것을 동적으로하고 싶다. 이 질문에 대한 코드의 위치는 QUESTION 문자열로 표시됩니다.

unsigned char *input; 
input = malloc(sizeof(unsigned char)*length); 
unsigned char input_question[length]; 

출력 :

[enc_dec_keystore] length: 82  
[enc_dec_keystore] QUESTION #1: why sizeof(input) != sizeof(input_question) 
[enc_dec_keystore] input size: 8 
[enc_dec_keystore] input_question size: 82 

를 sizeof (입력) 다른 이유. 이런 식으로 sizeof 포인터가 생기기 때문에? 도 sizeof (부호없는 문자)은 1이어야하고, 82를 곱하면 82가되어야합니다. 맞습니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <string.h> 
#include <openssl/aes.h> 
#include <openssl/evp.h> 
#include <openssl/sha.h> 

#define DEBUG 1 
#define KEYLEN 128 

void print_data(const char *tittle, const void* data, int len) 
{ 
    printf("%s : ",tittle); 
    const unsigned char * p = (const unsigned char*)data; 
    int i = 0; 

    for (; i<len; ++i) 
     printf("%02X ", *p++); 

    printf("\n"); 
} 

void PBKDF2_HMAC_SHA_512(const char *pass, const unsigned char *salt, int32_t iterations, uint32_t outputBytes, unsigned char *result) { 
    if (DEBUG) { 
     puts("[PBKDF2_HMAC_SHA_512] in"); 
    }  
    unsigned char digest[outputBytes]; 
    PKCS5_PBKDF2_HMAC(pass, strlen(pass), salt, strlen(salt), iterations, EVP_sha512(), outputBytes, digest); 
    for (int i = 0; i < sizeof(digest); i++) 
    {   
     result[i] = digest[i]; 
    }; 
    if (DEBUG) { 
     puts("[PBKDF2_HMAC_SHA_512] out"); 
    }  
} 

int deriver_key(const char *pass, const char *salt, unsigned char *key) { 
    if (DEBUG) { 
     puts("[deriver_key] in"); 
    } 
    /* allocate 16 bytes of memory for key (128 bits) */ 
    key = (unsigned char *) malloc(sizeof(unsigned char)*16); 
    /* let's make 10 iteration for now */ 
    PBKDF2_HMAC_SHA_512(pass, salt, 10, KEYLEN/8, key); 
    if (DEBUG) { 
     printf("[deriver_key] key(string): %s\n", key); 
     printf("[deriver_key] key(bytes): "); 
     for(int i=0; i<KEYLEN/8; i++) { 
      printf("%02x", key[i]); 
     } 
     printf("\n"); 
     puts("[deriver_key] out"); 
    } 

    return 0; 
} 

int enc_dec_keystore(char *keystore, char *key) { 
    /* length of keystore */ 
    int length; 
    /* if (length % AES_BLOCK_SIZE) !=0 -> fill to 16 bytes block */ 
    int pad_length; 
    int pad_counter = 0; 

    FILE *fp; 
    fp = fopen(keystore, "rb"); 
    fseek(fp, 0L, SEEK_END); 
    length = ftell(fp); 
    fseek(fp, 0L, SEEK_SET); 
    if (DEBUG) { 
     printf("[enc_dec_keystore] keystore length: %i\n", length); 
    } 

    /* check if input fills blocks correctly */ 
    pad_length = length;   
    while(pad_length % AES_BLOCK_SIZE !=0) { 
     pad_length++; 
     pad_counter++; 
    } 
    if (DEBUG) { 
     printf("[enc_dec_keystore] pad_length: %i\n", pad_length); 
    } 

    /* IV - fill with 0 for now */ 
    unsigned char iv[AES_BLOCK_SIZE]; 
    memset(iv, 0x00, AES_BLOCK_SIZE); 

    unsigned char *input; 
    input = malloc(sizeof(unsigned char)*length); 
    unsigned char input_question[length]; 
    if (DEBUG) { 
     printf("\n[enc_dec_keystore] QUESTION #1: why sizeof(input) != sizeof(input_question)\n"); 
     printf("[enc_dec_keystore] input size: %lu\n", sizeof(input)); 
     printf("[enc_dec_keystore] input_question size: %lu\n\n", sizeof(input_question)); 
    } 

    /* read data from file */ 
    int ret = 0; 
    ret = fread(input, 1, length, fp); 
    if (ret == 0) { 
     puts("[enc_dec_keystore] file doesn't exist"); 
    } 

    /* close the file after read */ 
    fclose(fp); 

    if (DEBUG) { 
     printf("[enc_dec_keystore] sizeof input: %lu, input length: %lu\n", sizeof(input), strlen(input)); 
     printf("[enc_dec_keystore] input data: \n%s\n", input); 
    }  
    /* allocate memory for aes's output */ 
    unsigned char *enc_out; 
    enc_out = malloc(sizeof(unsigned char)*pad_length); 
    unsigned char enc_out_question[pad_length]; 
    /* padding with 0 */ 
    memset(enc_out, 0, sizeof(enc_out));  
    if (DEBUG) { 
     printf("\n[enc_dec_keystore] QUESTION #2: (again) why sizeof(enc_out) != sizeof(enc_out_question)\n"); 
     printf("[enc_dec_keystore] enc_out size: %lu\n", sizeof(enc_out)); 
     printf("[enc_dec_keystore] enc_out_question size: %lu\n\n", sizeof(enc_out_question)); 
    } 

    /* AES-128 bit CBC Encryption */ 
    /* set up a key */ 
    /* 
    unsigned char key_again[KEYLEN/8]; 
    for (int i=0; i<KEYLEN/8; i++) { 
     key_again[i] = key[i]; 
    } 
    */ 
    AES_KEY enc_key; 
    AES_set_encrypt_key(key, 128, &enc_key); 
    /* encrypt input data to enc_out */ 
    AES_cbc_encrypt(input, enc_out, sizeof(input), &enc_key, iv, AES_ENCRYPT); 
    if (DEBUG) { 
     printf("[enc_dec_keystore] encryption - aes output(string): %s\n", enc_out); 
     printf("[enc_dec_keystore] encryption - aes output(bytes): "); 
     for(int i=0; i<pad_length; i++) { 
      printf("%02x", enc_out[i]); 
     } 
     printf("\n");  
    } 

    /* AES-128 bit CBC Decryption */ 
    /* 
    AES_KEY dec_key; 
    AES_set_encrypt_key(key, 128, &enc_key); 
    memset(iv, 0x00, AES_BLOCK_SIZE); 
    unsigned char *enc_out; 
    enc_out = malloc(sizeof(unsigned char)*pad_length); 
    AES_cbc_encrypt(enc_out, dec_out, sizeof(enc_out), &enc_key, iv, AES_ENCRYPT); 
    if (DEBUG) { 
     printf("[enc_dec_keystore] decryption - aes output(string): %s\n", enc_out); 
     printf("[enc_dec_keystore] decryption - aes output(bytes): "); 
     for(int i=0; i<pad_length; i++) { 
      printf("%02x", enc_out[i]); 
     } 
     printf("\n"); 
     puts("[enc_dec_keystore] out");  
    } 
    */ 

    return 0; 
} 

int main(int argc, char **argv) { 
    char *user = "user";  
    char *key_id = "key1"; 
    const char *pass = "temppass"; 
    const char *salt = "tempsalt"; 
    char *keystore = "keystore";  

    /* Deriver key from password and salt */ 
    unsigned char *key; 
    if (deriver_key(pass, salt, key) != 0) { 
     puts("[main] error with key derivery"); 
    } 

    /* Encrypt and decrypt keystore (for tests) */ 
    if (enc_dec_keystore(keystore, key) != 0) { 
     puts("[main] error with encrypting/decrypting keystore"); 
    } 


    return 0; 
} 

키 저장소 파일이 포함되어 있습니다 : 여기

내 프로그램에서 코드,

keyid1:01020304050607080900010203040506: 
keyid2:06050403020100090807060504030201: 

답변

0

를 sizeof (입력) (82)없는 이유는 포인터 변수를 sizeof 만 반환 크기 때문에, 동적으로 할당 된 데이터의 크기를 반환하지 않습니다. PBKDF2_HMAC_SHA_512는 '\ 0'으로 구분되지 않는 이진 키를 반환합니다. 키를 인쇄 할 때 segfault가 발생할 수 있습니다.

+0

좋습니다.이 sizeof가 포인터 크기를 반환한다고 제안했습니다. 확인해 주셔서 감사합니다. AES_cbc_encrypt가 호출되는 동안 Segfault가 반환됩니다. 그래서 동적으로 할당 된 테이블의 크기를 갖는 유일한 방법은 ** 길이 ** 값 ie를 저장하는 것입니다. size_t 변수에? –