2014-11-19 3 views
1

GMAC 용 인터페이스로 openssl EVP (EVP_aes_128_gcm)를 사용하려고합니다. NIST의 CAVP GCM 테스트 벡터 (http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip)에 대해 코드를 테스트하고 있습니다. 문제는 : 아드 크기가 16의 배수 일 때, 코드는 정확한 GMAC 태그를 줄 수 있습니다. 그러나 크기가 16의 배수가 아니면 결과가 잘못됩니다. 무엇이 문제 일 수 있습니까?16의 배수가 아닌 아디드에 대해 openssl에서 EVP_aes_128_gcm을 사용합니다.

코드는 다음과 같습니다 테스트 벡터를 들어

#include <openssl/bn.h> 
#include <openssl/rsa.h> 
#include <openssl/pem.h> 
#include <openssl/evp.h> 
#include <openssl/rand.h> 
#include <openssl/engine.h> 

#include <assert.h> 
#include <stdio.h> 

void dump(const void *p, size_t len) 
{ 
    const unsigned char *a = p; 
    size_t i; 
    for (i = 0; i < len; i++) { 
     printf("%02x", a[i]); 
    } 
    puts(""); 
} 

void main(void){ 

    /* 
    // key = 16; aad = 20; WRONG tag computed 
    u_char key[] = {0x2f,0xb4,0x5e,0x5b,0x8f,0x99,0x3a,0x2b,0xfe,0xbc,0x4b,0x15,0xb5,0x33,0xe0,0xb4}; 
    u_char iv[] = {0x5b,0x05,0x75,0x5f,0x98,0x4d,0x2b,0x90,0xf9,0x4b,0x80,0x27}; 
    u_char aad[] = {0xe8,0x54,0x91,0xb2,0x20,0x2c,0xaf,0x1d,0x7d,0xce,0x03,0xb9,0x7e,0x09,0x33,0x1c, 
        0x32,0x47,0x39,0x41}; 
    u_char tag[16] = {}; 
    u_char exp[] = {0xc7,0x5b,0x78,0x32,0xb2,0xa2,0xd9,0xbd,0x82,0x74,0x12,0xb6,0xef,0x57,0x69,0xdb}; // expected result 
    */ 

    // key = 16; aad = 48; CORRECTED tag computed 
    u_char key[] = {0x99,0xe3,0xe8,0x79,0x3e,0x68,0x6e,0x57,0x1d,0x82,0x85,0xc5,0x64,0xf7,0x5e,0x2b}; 
    u_char iv[] = {0xc2,0xdd,0x0a,0xb8,0x68,0xda,0x6a,0xa8,0xad,0x9c,0x0d,0x23}; 
    u_char aad[] = {0xb6,0x68,0xe4,0x2d,0x4e,0x44,0x4c,0xa8,0xb2,0x3c,0xfd,0xd9,0x5a,0x9f,0xed,0xd5, 
        0x17,0x8a,0xa5,0x21,0x14,0x48,0x90,0xb0,0x93,0x73,0x3c,0xf5,0xcf,0x22,0x52,0x6c, 
        0x59,0x17,0xee,0x47,0x65,0x41,0x80,0x9a,0xc6,0x86,0x7a,0x8c,0x39,0x93,0x09,0xfc}; 

    u_char tag[16] = {}; 
    u_char exp[] = {0x3f,0x4f,0xba,0x10,0x0e,0xaf,0x1f,0x34,0xb0,0xba,0xad,0xaa,0xe9,0x99,0x5d,0x85}; // expected result 


    int rc = 0, unused; 
    unsigned int i; 
    EVP_CIPHER_CTX *ctx = NULL; 

    ctx = EVP_CIPHER_CTX_new(); 
    assert(ctx != NULL); 

    rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); 
    assert(rc == 1); 

    rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL); 
    assert(rc == 1); 

    rc = EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv); 
    assert(rc == 1); 

    rc = EVP_EncryptUpdate(ctx, NULL, &unused, aad, sizeof(aad)); 
    assert(rc == 1); 

    rc = EVP_EncryptFinal_ex(ctx, NULL, &unused); 
    assert(rc == 1); 

    rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof(tag), tag); 
    assert(rc == 1); 

    EVP_CIPHER_CTX_free(ctx); 

    printf("should be: "); 
    dump(exp, sizeof(exp)); 
    printf("result is: "); 
    dump(tag, sizeof(tag)); 

} 

(코드에서 주석 섹션) :

[Keylen = 128] 
[IVlen = 96] 
[PTlen = 0] 
[AADlen = 160] 
[Taglen = 128] 

Count = 0 
Key = 2fb45e5b8f993a2bfebc4b15b533e0b4 
IV = 5b05755f984d2b90f94b8027 
PT = 
AAD = e85491b2202caf1d7dce03b97e09331c32473941 
CT = 
Tag = c75b7832b2a2d9bd827412b6ef5769db 

출력이 잘못 ...를 들어

should be: c75b7832b2a2d9bd827412b6ef5769db 
result is: e5fb99cb5b9658aa5d2caa3308e0ce6c 

시험 벡터 :

[Keylen = 128] 
[IVlen = 96] 
[PTlen = 0] 
[AADlen = 384] 
[Taglen = 128] 

Count = 0 
Key = 99e3e8793e686e571d8285c564f75e2b 
IV = c2dd0ab868da6aa8ad9c0d23 
PT = 
AAD = b668e42d4e444ca8b23cfdd95a9fedd5178aa521144890b093733cf5cf22526c5917ee476541809ac6867a8c399309fc 
CT = 
Tag = 3f4fba100eaf1f34b0baadaae9995d85 
012 3,516,

출력은 올바른 : 내가 사용하고

should be: 3f4fba100eaf1f34b0baadaae9995d85 
result is: 3f4fba100eaf1f34b0baadaae9995d85 

버전은 다음과 같습니다 은 OpenSSL 1.0.1 2012년 3월 14일

+0

흥미로운 것은 암호문을 제공하지 않으면 채우기가 잘못 계산 된 것일 수 있습니다. 실제 잘못된 출력을 보여 주시겠습니까? 오픈 SSL 호환 RT를 직접 사용할 수 없습니다. 또한 OpenSSL의 버전 번호를 제공 할 수 있습니까? 버그 일 수 있습니다 ... 오, 테스트 벡터가 사용 되었습니까? 죄송 당신을 너무 많이 괴롭히지 :) –

+0

코드에 직접적인 문제가 보이지 않으며 Java가 예상 값을 생성합니다. –

+0

빠른 답장을 보내 주셔서 감사합니다! AAD 길이가 키 길이와 같지 않은 케이스를 시도해 보셨습니까? – Tom

답변

0

내가 최근에는 OpenSSL (OpenSSL을 1.0.1j 2014년 10월 15일)를 다운로드했습니다. 수정 된 결과를 제공합니다. 우분투 12.04LTS의 openssl (OpenSSL 1.0.1 14 Mar 2012)에이 특정 GMAC 응용 프로그램에 버그가있을 수 있습니다.

정말 고맙습니다. 코드가 맞는지 확인합니다.

BTW. 사실 나는 다른 질문을 할 수 있습니다. 어떻게 openssl 버전을 사용하는 것이 좋은지 어떻게 알 수 있습니까?

+0

보안 라이브러리의 경우 유일한 좋은 대답은 "최신"버전입니다 (다시 디자인하지 않음). 경우에 따라 보안 픽스 만 적용된 버전을 선택할 수도 있습니다. 응용 프로그램을 최신 상태로 유지하십시오. 또한 기능과 속도를 높이기 위해 보안을 적용하는 런타임 (예 : Java)을 사용해보십시오. OpenSSL에서 본 내용에 깊은 인상을 받았습니다 (NSS는 아마도 더 나빠질 것입니다). –

관련 문제