/* tlsprfalg.c - TLS Pseudo Random Function (PRF) implementation
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif

#include "blapi.h"
#include "hasht.h"
#include "alghmac.h"

#define PHASH_STATE_MAX_LEN HASH_LENGTH_MAX

/* TLS P_hash function */
SECStatus
TLS_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
           SECItem *seed, SECItem *result, PRBool isFIPS)
{
    unsigned char state[PHASH_STATE_MAX_LEN];
    unsigned char outbuf[PHASH_STATE_MAX_LEN];
    unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
    unsigned int remaining;
    unsigned char *res;
    SECStatus status;
    HMACContext *cx;
    SECStatus rv = SECFailure;
    const SECHashObject *hashObj = HASH_GetRawHashObject(hashType);

    PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
    PORT_Assert((seed != NULL) && (seed->data != NULL));
    PORT_Assert((result != NULL) && (result->data != NULL));

    remaining = result->len;
    res = result->data;

    if (label != NULL)
        label_len = PORT_Strlen(label);

    cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
    if (cx == NULL)
        goto loser;

    /* initialize the state = A(1) = HMAC_hash(secret, seed) */
    HMAC_Begin(cx);
    HMAC_Update(cx, (unsigned char *)label, label_len);
    HMAC_Update(cx, seed->data, seed->len);
    status = HMAC_Finish(cx, state, &state_len, sizeof(state));
    if (status != SECSuccess)
        goto loser;

    /* generate a block at a time until we're done */
    while (remaining > 0) {

        HMAC_Begin(cx);
        HMAC_Update(cx, state, state_len);
        if (label_len)
            HMAC_Update(cx, (unsigned char *)label, label_len);
        HMAC_Update(cx, seed->data, seed->len);
        status = HMAC_Finish(cx, outbuf, &outbuf_len, sizeof(outbuf));
        if (status != SECSuccess)
            goto loser;

        /* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
        HMAC_Begin(cx);
        HMAC_Update(cx, state, state_len);
        status = HMAC_Finish(cx, state, &state_len, sizeof(state));
        if (status != SECSuccess)
            goto loser;

        chunk_size = PR_MIN(outbuf_len, remaining);
        PORT_Memcpy(res, &outbuf, chunk_size);
        res += chunk_size;
        remaining -= chunk_size;
    }

    rv = SECSuccess;

loser:
    /* clear out state so it's not left on the stack */
    if (cx)
        HMAC_Destroy(cx, PR_TRUE);
    PORT_Memset(state, 0, sizeof(state));
    PORT_Memset(outbuf, 0, sizeof(outbuf));
    return rv;
}

SECStatus
TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
        SECItem *result, PRBool isFIPS)
{
    SECStatus rv = SECFailure, status;
    unsigned int i;
    SECItem tmp = { siBuffer, NULL, 0 };
    SECItem S1;
    SECItem S2;

    PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
    PORT_Assert((seed != NULL) && (seed->data != NULL));
    PORT_Assert((result != NULL) && (result->data != NULL));

    S1.type = siBuffer;
    S1.len = (secret->len / 2) + (secret->len & 1);
    S1.data = secret->data;

    S2.type = siBuffer;
    S2.len = S1.len;
    S2.data = secret->data + (secret->len - S2.len);

    tmp.data = (unsigned char *)PORT_Alloc(result->len);
    if (tmp.data == NULL)
        goto loser;
    tmp.len = result->len;

    status = TLS_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
    if (status != SECSuccess)
        goto loser;

    status = TLS_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
    if (status != SECSuccess)
        goto loser;

    for (i = 0; i < result->len; i++)
        result->data[i] ^= tmp.data[i];

    rv = SECSuccess;

loser:
    if (tmp.data != NULL)
        PORT_ZFree(tmp.data, tmp.len);
    return rv;
}
