int HKDF_SHA256_expand()

in src/hkdf.c [57:94]


int HKDF_SHA256_expand(char *okm, unsigned int okmlen,
    const char *prk, unsigned int prklen,
    const char *info, unsigned int infolen)
{
    if (okm == NULL || prk == NULL)
        return ERR_NULLPOINTER_HKDF;
    if (prklen != SHA256_HASH_SIZE || okmlen > 255*SHA256_HASH_SIZE)
        return ERR_BADARGLEN_HKDF;

    unsigned int i;
    int ret = SUCCESS;
    char count = 0x01;
    char tmp[SHA256_HASH_SIZE];

    hmac_sha256 ctx;
    ret |= HMAC_SHA256_init(&ctx, prk, SHA256_HASH_SIZE);
    ret |= HMAC_SHA256_update(&(ctx.sha256_ctx), info, infolen);
    ret |= HMAC_SHA256_update(&(ctx.sha256_ctx), &count, 1);
    ret |= HMAC_SHA256_final(&ctx, tmp, SHA256_HASH_SIZE);

    while (okmlen > SHA256_HASH_SIZE) {
        count++;
        for(i = 0; i < SHA256_HASH_SIZE; i++)
            okm[i] = tmp[i];
        okm     += SHA256_HASH_SIZE;
        okmlen  -= SHA256_HASH_SIZE;
        ret |= HMAC_SHA256_init(&ctx, prk, SHA256_HASH_SIZE);
        ret |= HMAC_SHA256_update(&(ctx.sha256_ctx), tmp, SHA256_HASH_SIZE);
        ret |= HMAC_SHA256_update(&(ctx.sha256_ctx), info, infolen);
        ret |= HMAC_SHA256_update(&(ctx.sha256_ctx), &count, 1);
        ret |= HMAC_SHA256_final(&ctx, tmp, SHA256_HASH_SIZE);
    }

    for(i = 0; i < okmlen; i++)
        okm[i] = tmp[i];

    return ret;
}