Search code examples
hmacsgx

SGX calculating HMAC inside enclave


I'm trying to calculate an HMAC with SHA512 inside an Intel SGX enclave. I got the code to work but receive the wrong results. I have an example that uses static pre-defined key and nonce from which the HMAC is calculated, but when verifying the received result it does not match the correct one.

Apparantely there are two different variants to calculate the HMAC (according to this enter link description here, I've tried both.

Here is the function from the enclave:

int calculateHMAC(uint8_t *key, uint8_t *nonce, uint8_t *res_hmac) {
    IppsHMACState *ctx;
    IppStatus status;
    int psize = 0;

    //VARIANT 1
    status = ippsHMAC_GetSize(&psize);

    if (status == ippStsNullPtrErr) 
        return 1;

    ctx = (IppsHMACState*) malloc(psize);
    status = ippsHMAC_Init(key, 16, ctx, ippHashAlg_SHA512);

    if (status != ippStsNoErr)
        return 1;

    status = ippsHMAC_Update(nonce, 16, ctx);

    if (status != ippStsNoErr)
        return 1;

    uint8_t hmac[64];
    memset(hmac, '\0', 64);
    status = ippsHMAC_Final(hmac, 64, ctx);

    if (status != ippStsNoErr)
        return 1;

    memcpy(res_hmac, hmac, 64);

    //VARIANT 2
//  uint8_t test_hmac[HMAC_LENGTH];
//  status = ippsHMAC_Message(nonce, 16, key, 16, test_hmac, 64, ippHashAlg_SHA512);

//  if (status != ippStsNoErr)
//      return 1;

//  memcpy(res_hmac, test_hmac, 64);

    return 0;

}

Here is the UPDATED call:

uint8_t ba_nonce[16] = {
    0x7d, 0x93, 0x09, 0x9f, 0x7f, 0xed, 0x16, 0x21,
    0x58, 0x36, 0xf7, 0xba, 0xd4, 0xdb, 0x0e, 0x48
};

uint8_t ba_key[16] = {
    0xa5, 0xb1, 0x15, 0x53, 0x6d, 0x5b, 0xf3, 0x50,
    0xc5, 0xb0, 0xfa, 0x6f, 0x69, 0x24, 0x2f, 0x18
};

uint8_t t_hmac[64];
memset(t_hmac, '\0', 64);

int error = calculateHMAC(ba_key, ba_nonce, t_hmac);

I don't see what I'm doing wrong!?

This will result in 7d2f2e3d57c84a58945b9016fb37e2df03afdde313c9d79c31ec1e6612d6d6b20456a8fcf799ef74d16f60c7f283e621400004422885f33fb3d2bb7ae7a1daa3

which is wrong according to this calculator here


Solution

  • Your issue is strtol(). It expects a string. In C a string is an arbitrary sequence of characters terminated with a NULL-byte. However, it is provided a pointer to an array of size two where the last entry is not NULL. Therefore, strtol() also analysis the bytes behind your tmp array.

    Since, tmp is stored on the stack we can not assume that the subsequent bytes are always the same for different invocations. Thus, you get random results.

    Solution: Either, you increase the size of tmp and add a NULL byte in the last place or - and this is probably the better solution - you directly initialize nonce and key with what you need (see also this post):

    uint8_t ba_nonce[16] = {
        0x7d, 0x93, 0x09, 0x9f, 0x7f, 0xed, 0x16, 0x21,
        0x58, 0x36, 0xf7, 0xba, 0xd4, 0xdb, 0x0e, 0x48
    };
    
    uint8_t ba_key[16] = {
        0xa5, 0xb1, 0x15, 0x53, 0x6d, 0x5b, 0xf3, 0x50,
        0xc5, 0xb0, 0xfa, 0x6f, 0x69, 0x24, 0x2f, 0x18
    };