int HMAC_SHA256_oneshot()

in src/hmac.c [113:170]


int HMAC_SHA256_oneshot(char* out,  int outlen,
    const char* key,  int keylen,
    const char* in,  int inlen)
{
    if (out == NULL || key == NULL || in == NULL)
        return ERR_NULLPOINTER_HMAC;
    if (keylen < SHA256_HASH_SIZE)
        return ERR_KEYSIZE_HMAC;
    if (outlen <= 0 || outlen > SHA256_HASH_SIZE || inlen < 0)
        return ERR_BADARGLEN_HMAC;

    int i;
    hash256 sha256;
    char ipad = 0x36;
    char opad = 0x5c;
    char k0[SHA256_BLOCK_SIZE];
    char digest[SHA256_HASH_SIZE];

    HASH256_init(&sha256);
    // Fill k0 with 0s for future padding
    for(i = 0; i < SHA256_BLOCK_SIZE; i++)
        k0[i] = 0x00;

    // If the key size is larger than the block size, then hash it
    if (keylen > SHA256_BLOCK_SIZE) {
        for(i = 0; i < keylen; i++)
            HASH256_process(&sha256, key[i]);
        HASH256_hash(&sha256, k0);
    }
    // Otherwise the key is simply padded with 0s into k0
    else {
        for(i = 0; i < keylen; i++)
            k0[i] = key[i];
    }

    // Compute H((k0 ^ ipad) || in)
    for(i = 0; i < SHA256_BLOCK_SIZE; i++)
        HASH256_process(&sha256, k0[i] ^ ipad);
    for(i = 0; i < inlen; i++)
        HASH256_process(&sha256, in[i]);
    HASH256_hash(&sha256, digest);

    // Compute `H((k0 ^ opad ) || H((k0 ^ ipad) || in))`
    for(i = 0; i < SHA256_BLOCK_SIZE; i++)
        HASH256_process(&sha256, k0[i] ^ opad);
    for(i = 0; i < SHA256_HASH_SIZE; i++)
        HASH256_process(&sha256, digest[i]);
    HASH256_hash(&sha256, digest);

    // Erase the secret key as it is not needed anymore
    for(i = 0; i < SHA256_BLOCK_SIZE; i++)
        k0[i] = 0x00;

    for(i = 0; i < outlen; i++)
        out[i] = digest[i];

    return SUCCESS;
}