#include "pkcs11i.h"
#include "blapi.h"
#include "secerr.h"
#include "softoken.h"

/* Overview:
 *
 * This file contains implementations of the three KDFs from NIST SP800-108
 * "Recommendation for Key Derivation Using Pseudorandom Functions":
 *
 *  1. KDF in Counter Mode (section 5.1)
 *  2. KDF in Feedback Mode (section 5.2)
 *  3. KDF in Double-Pipeline Iteration Mode (section 5.3)
 *
 * These KDFs are a form of negotiable building blocks for KDFs: protocol
 * designers can choose various fields, their endianness, and the underlying
 * PRF. These constructs are generic enough to handle creation of arbitrary,
 * (but known ahead of time) length outputs.
 *
 * The families of PRFs described here are used, among other places, in
 * Kerberos and GlobalPlatform's Secure Channel Protocol 03. The PKCS#11 v3.0
 * design for this KDF facilitates a wide range of uses.
 *
 * Implementation Details:
 *
 * We reuse the new sftk_MACCtx for handling the underlying MACing; with a few
 * safe restrictions, we can reuse whatever it gives us to use as a PRF.
 *
 * We implement the core of the KDF in the *Raw(...) version of the function
 * call. The PKCS#11 key handling happens in the non-Raw version. This means
 * we need a single large allocation upfront (large enough to store the entire
 * key stream), but means we can share key parsing logic and enable the
 * creation of data objects.
 */

/* [ section: #define's ] */

#define VALID_CK_BOOL(x) ((x) == CK_TRUE || (x) == CK_FALSE)
#define IS_COUNTER(_mech) ((_mech) == CKM_SP800_108_COUNTER_KDF || (_mech) == CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA)
#define DOES_DERIVE_DATA(_mech) ((_mech) == CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA || (_mech) == CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA || (_mech) == CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA)

/* [ section: parameter validation ] */

static CK_RV
kbkdf_LoadParameters(CK_MECHANISM_TYPE mech, CK_MECHANISM_PTR pMechanism, CK_SP800_108_KDF_PARAMS_PTR kdf_params, CK_BYTE_PTR *initial_value, CK_ULONG_PTR initial_value_length)
{
    /* This function loads the parameters for the given mechanism into the
     * specified kdf_params, splitting off the IV if present. In PKCS#11 v3.0,
     * CK_SP800_108_FEEDBACK_KDF_PARAMS and CK_SP800_108_KDF_PARAMS have
     * different ordering of internal parameters, which means that it isn't
     * easy to reuse feedback parameters in the same functions as non-feedback
     * parameters. Rather than duplicating the logic, split out the only
     * Feedback-specific data (the IV) into a separate argument and repack it
     * into the passed kdf_params struct instead. */
    PR_ASSERT(pMechanism != NULL && kdf_params != NULL && initial_value != NULL && initial_value_length != NULL);

    CK_SP800_108_KDF_PARAMS_PTR in_params;
    CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR feedback_params;

    if (mech == CKM_SP800_108_FEEDBACK_KDF || mech == CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA) {
        if (pMechanism->ulParameterLen != sizeof(CK_SP800_108_FEEDBACK_KDF_PARAMS)) {
            return CKR_MECHANISM_PARAM_INVALID;
        }

        feedback_params = (CK_SP800_108_FEEDBACK_KDF_PARAMS *)pMechanism->pParameter;

        if (feedback_params->pIV == NULL && feedback_params->ulIVLen > 0) {
            return CKR_MECHANISM_PARAM_INVALID;
        }

        kdf_params->prfType = feedback_params->prfType;
        kdf_params->ulNumberOfDataParams = feedback_params->ulNumberOfDataParams;
        kdf_params->pDataParams = feedback_params->pDataParams;
        kdf_params->ulAdditionalDerivedKeys = feedback_params->ulAdditionalDerivedKeys;
        kdf_params->pAdditionalDerivedKeys = feedback_params->pAdditionalDerivedKeys;

        *initial_value = feedback_params->pIV;
        *initial_value_length = feedback_params->ulIVLen;
    } else {
        if (pMechanism->ulParameterLen != sizeof(CK_SP800_108_KDF_PARAMS)) {
            return CKR_MECHANISM_PARAM_INVALID;
        }

        in_params = (CK_SP800_108_KDF_PARAMS *)pMechanism->pParameter;

        (*kdf_params) = *in_params;
    }

    return CKR_OK;
}

static CK_RV
kbkdf_ValidateParameter(CK_MECHANISM_TYPE mech, const CK_PRF_DATA_PARAM *data)
{
    /* This function validates that the passed data parameter (data) conforms
     * to PKCS#11 v3.0's expectations for KDF parameters. This depends both on
     * the type of this parameter (data->type) and on the KDF mechanism (mech)
     * as certain parameters are context dependent (like Iteration Variable).
     */

    /* If the parameter is missing a value when one is expected, then this
     * parameter is invalid. */
    if ((data->pValue == NULL) != (data->ulValueLen == 0)) {
        return CKR_MECHANISM_PARAM_INVALID;
    }

    switch (data->type) {
        case CK_SP800_108_ITERATION_VARIABLE:
        case CK_SP800_108_OPTIONAL_COUNTER: {
            if (data->type == CK_SP800_108_ITERATION_VARIABLE && !IS_COUNTER(mech)) {
                /* In Feedback and Double Pipeline KDFs, PKCS#11 v3.0 connotes the
                 * iteration variable as the chaining value from the previous PRF
                 * invocation. In contrast, counter mode treats this variable as a
                 * COUNTER_FORMAT descriptor. Thus we can skip validation of
                 * iteration variable parameters outside of counter mode. However,
                 * PKCS#11 v3.0 technically mandates that pValue is NULL, so we
                 * still have to validate that. */

                if (data->pValue != NULL) {
                    return CKR_MECHANISM_PARAM_INVALID;
                }

                return CKR_OK;
            }

            /* In counter mode, data->pValue should be a pointer to an instance of
             * CK_SP800_108_COUNTER_FORMAT; validate its length. */
            if (data->ulValueLen != sizeof(CK_SP800_108_COUNTER_FORMAT)) {
                return CKR_MECHANISM_PARAM_INVALID;
            }

            CK_SP800_108_COUNTER_FORMAT_PTR param = (CK_SP800_108_COUNTER_FORMAT_PTR)data->pValue;

            /* Validate the endian parameter. */
            if (!VALID_CK_BOOL(param->bLittleEndian)) {
                return CKR_MECHANISM_PARAM_INVALID;
            }

            /* Due to restrictions by our underlying hashes, we restrict bit
             * widths to actually be byte widths by ensuring they're a multiple
             * of eight. */
            if ((param->ulWidthInBits % 8) != 0) {
                return CKR_MECHANISM_PARAM_INVALID;
            }

            /* Note that section 5.1 denotes the maximum length of the counter
             * to be 32. */
            if (param->ulWidthInBits > 32) {
                return CKR_MECHANISM_PARAM_INVALID;
            }
            break;
        }
        case CK_SP800_108_DKM_LENGTH: {
            /* data->pValue should be a pointer to an instance of
             * CK_SP800_108_DKM_LENGTH_FORMAT; validate its length. */
            if (data->ulValueLen != sizeof(CK_SP800_108_DKM_LENGTH_FORMAT)) {
                return CKR_MECHANISM_PARAM_INVALID;
            }

            CK_SP800_108_DKM_LENGTH_FORMAT_PTR param = (CK_SP800_108_DKM_LENGTH_FORMAT_PTR)data->pValue;

            /* Validate the method parameter. */
            if (param->dkmLengthMethod != CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS &&
                param->dkmLengthMethod != CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS) {
                return CKR_MECHANISM_PARAM_INVALID;
            }

            /* Validate the endian parameter. */
            if (!VALID_CK_BOOL(param->bLittleEndian)) {
                return CKR_MECHANISM_PARAM_INVALID;
            }

            /* Validate the maximum width: we restrict it to being a byte width
             * instead of a bit width due to restrictions by the underlying
             * PRFs. */
            if ((param->ulWidthInBits % 8) != 0) {
                return CKR_MECHANISM_PARAM_INVALID;
            }

            /* Ensure that the width doesn't overflow a 64-bit int. This
             * restriction is arbitrary but since the counters can't exceed
             * 32-bits (and most PRFs output at most 1024 bits), you're unlikely
             * to need all 64-bits of length indicator. */
            if (param->ulWidthInBits > 64) {
                return CKR_MECHANISM_PARAM_INVALID;
            }
            break;
        }
        case CK_SP800_108_BYTE_ARRAY:
            /* There is no additional data to validate for byte arrays; we can
             * only assume the byte array is of the specified size. */
            break;
        default:
            /* Unexpected parameter type. */
            return CKR_MECHANISM_PARAM_INVALID;
    }

    return CKR_OK;
}

static CK_RV
kbkdf_ValidateDerived(CK_DERIVED_KEY_PTR key)
{
    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    PRUint64 keySize = 0;

    /* The pointer to the key handle shouldn't be NULL. If it is, we can't
     * do anything else, so exit early. Every other failure case sets the
     * key->phKey = CK_INVALID_HANDLE, so we can't use `goto failure` here. */
    if (key->phKey == NULL) {
        return CKR_MECHANISM_PARAM_INVALID;
    }

    /* Validate that we have no attributes if and only if pTemplate is NULL.
     * Otherwise, there's an inconsistency somewhere. */
    if ((key->ulAttributeCount == 0) != (key->pTemplate == NULL)) {
        goto failure;
    }

    for (size_t offset = 0; offset < key->ulAttributeCount; offset++) {
        CK_ATTRIBUTE_PTR template = key->pTemplate + offset;

        /* We only look for the CKA_VALUE_LEN and CKA_KEY_TYPE attributes.
         * Everything else we assume we can set on the key if it is passed
         * here. However, if we can't inquire as to a length (and barring
         * that, if we have a key type without a standard length), we're
         * definitely stuck. This mirrors the logic at the top of
         * NSC_DeriveKey(...). */
        if (template->type == CKA_KEY_TYPE) {
            if (template->ulValueLen != sizeof(CK_KEY_TYPE)) {
                goto failure;
            }

            keyType = *(CK_KEY_TYPE *)template->pValue;
        } else if (template->type == CKA_VALUE_LEN) {
            if (template->ulValueLen != sizeof(CK_ULONG)) {
                goto failure;
            }

            keySize = *(CK_ULONG *)template->pValue;
        }
    }

    if (keySize == 0) {
        /* When we lack a keySize, see if we can infer it from the type of the
         * passed key. */
        keySize = sftk_MapKeySize(keyType);
    }

    /* The main piece of information we validate is that we have a length for
     * this key. */
    if (keySize == 0 || keySize >= (1ull << 32ull)) {
        goto failure;
    }

    return CKR_OK;

failure:
    /* PKCS#11 v3.0: If the failure was caused by the content of a specific
     * key's template (ie the template defined by the content of pTemplate),
     * the corresponding phKey value will be set to CK_INVALID_HANDLE to
     * identify the offending template. */
    *(key->phKey) = CK_INVALID_HANDLE;
    return CKR_MECHANISM_PARAM_INVALID;
}

static CK_RV
kbkdf_ValidateParameters(CK_MECHANISM_TYPE mech, const CK_SP800_108_KDF_PARAMS *params, CK_ULONG keySize)
{
    CK_RV ret = CKR_MECHANISM_PARAM_INVALID;
    int param_type_count[5] = { 0, 0, 0, 0, 0 };
    size_t offset = 0;

    /* Start with checking the prfType as a mechanism against a list of
     * PRFs allowed by PKCS#11 v3.0. */
    if (!(/* The following types aren't defined in NSS yet. */
          /* params->prfType != CKM_3DES_CMAC && */
          params->prfType == CKM_AES_CMAC || /* allow */
          /* We allow any HMAC except MD2 and MD5. */
          params->prfType != CKM_MD2_HMAC ||                        /* disallow */
          params->prfType != CKM_MD5_HMAC ||                        /* disallow */
          sftk_HMACMechanismToHash(params->prfType) != HASH_AlgNULL /* Valid HMAC <-> HASH isn't NULL */
          )) {
        return CKR_MECHANISM_PARAM_INVALID;
    }

    /* We can't have a null pDataParams pointer: we always need at least one
     * parameter to succeed. */
    if (params->pDataParams == NULL) {
        return CKR_HOST_MEMORY;
    }

    /* Validate each KDF parameter. */
    for (offset = 0; offset < params->ulNumberOfDataParams; offset++) {
        /* Validate this parameter has acceptable values. */
        ret = kbkdf_ValidateParameter(mech, params->pDataParams + offset);
        if (ret != CKR_OK) {
            return CKR_MECHANISM_PARAM_INVALID;
        }

        /* Count that we have a parameter of this type. The above logic
         * in ValidateParameter MUST validate that type is within the
         * appropriate range. */
        PR_ASSERT(params->pDataParams[offset].type < sizeof(param_type_count) / sizeof(param_type_count[0]));
        param_type_count[params->pDataParams[offset].type] += 1;
    }

    if (IS_COUNTER(mech)) {
        /* We have to have at least one iteration variable parameter. */
        if (param_type_count[CK_SP800_108_ITERATION_VARIABLE] == 0) {
            return CKR_MECHANISM_PARAM_INVALID;
        }

        /* We can't have any optional counters parameters -- these belong in
         * iteration variable parameters instead. */
        if (param_type_count[CK_SP800_108_OPTIONAL_COUNTER] != 0) {
            return CKR_MECHANISM_PARAM_INVALID;
        }
    }

    /* Validate basic assumptions about derived keys:
     *      NULL <-> ulAdditionalDerivedKeys > 0
     */
    if ((params->ulAdditionalDerivedKeys == 0) != (params->pAdditionalDerivedKeys == NULL)) {
        return CKR_MECHANISM_PARAM_INVALID;
    }

    /* Validate each derived key. */
    for (offset = 0; offset < params->ulAdditionalDerivedKeys; offset++) {
        ret = kbkdf_ValidateDerived(params->pAdditionalDerivedKeys + offset);
        if (ret != CKR_OK) {
            return CKR_MECHANISM_PARAM_INVALID;
        }
    }

    /* Validate the length of our primary key. */
    if (keySize == 0 || ((PRUint64)keySize) >= (1ull << 32ull)) {
        return CKR_KEY_SIZE_RANGE;
    }

    return CKR_OK;
}

/* [ section: parameter helpers ] */

static CK_VOID_PTR
kbkdf_FindParameter(const CK_SP800_108_KDF_PARAMS *params, CK_PRF_DATA_TYPE type)
{
    for (size_t offset = 0; offset < params->ulNumberOfDataParams; offset++) {
        if (params->pDataParams[offset].type == type) {
            return params->pDataParams[offset].pValue;
        }
    }

    return NULL;
}

size_t
kbkdf_IncrementBuffer(size_t cur_offset, size_t consumed, size_t prf_length)
{
    return cur_offset + PR_ROUNDUP(consumed, prf_length);
}

CK_ULONG
kbkdf_GetDerivedKeySize(CK_DERIVED_KEY_PTR derived_key)
{
    /* Precondition: kbkdf_ValidateDerived(...) returns CKR_OK for this key,
     * which implies that keySize is defined. */

    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    CK_ULONG keySize = 0;

    for (size_t offset = 0; offset < derived_key->ulAttributeCount; offset++) {
        CK_ATTRIBUTE_PTR template = derived_key->pTemplate + offset;

        /* Find the two attributes we care about. */
        if (template->type == CKA_KEY_TYPE) {
            keyType = *(CK_KEY_TYPE *)template->pValue;
        } else if (template->type == CKA_VALUE_LEN) {
            keySize = *(CK_ULONG *)template->pValue;
        }
    }

    /* Prefer keySize, if we have it. */
    if (keySize > 0) {
        return keySize;
    }

    /* Else, fall back to this mapping. We know kbkdf_ValidateDerived(...)
     * passed, so this should return non-zero. */
    return sftk_MapKeySize(keyType);
}

static CK_RV
kbkdf_CalculateLength(const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, CK_ULONG ret_key_size, PRUint64 *output_bitlen, size_t *buffer_length)
{
    /* Two cases: either we have additional derived keys or we don't. In the
     * case that we don't, the length of the derivation is the size of the
     * single derived key, and that is the length of the PRF buffer. Otherwise,
     * we need to use the proper CK_SP800_108_DKM_LENGTH_METHOD to calculate
     * the length of the output (in bits), with a separate value for the size
     * of the PRF data buffer. This means that, under PKCS#11 with additional
     * derived keys, we lie to the KDF about the _actual_ length of the PRF
     * output.
     *
     * Note that *output_bitlen is the L parameter in NIST SP800-108 and is in
     * bits. However, *buffer_length is in bytes.
     */

    if (params->ulAdditionalDerivedKeys == 0) {
        /* When we have no additional derived keys, we get the keySize from
         * the value passed to one of our KBKDF_* methods. */
        *output_bitlen = ret_key_size;
        *buffer_length = ret_key_size;
    } else {
        /* Offset in the additional derived keys array. */
        size_t offset = 0;

        /* Size of the derived key. */
        CK_ULONG derived_size = 0;

        /* In the below, we place the sum of the keys into *output_bitlen
         * and the size of the buffer (with padding mandated by PKCS#11 v3.0)
         * into *buffer_length. If the method is the segment sum, then we
         * replace *output_bitlen with *buffer_length at the end. This ensures
         * we always get a output buffer large enough to handle all derived
         * keys, and *output_bitlen reflects the correct L value. */

        /* Count the initial derived key. */
        *output_bitlen = ret_key_size;
        *buffer_length = kbkdf_IncrementBuffer(0, ret_key_size, ctx->mac_size);

        /* Handle n - 1 keys. The last key is special. */
        for (; offset < params->ulAdditionalDerivedKeys - 1; offset++) {
            derived_size = kbkdf_GetDerivedKeySize(params->pAdditionalDerivedKeys + offset);

            *output_bitlen += derived_size;
            *buffer_length = kbkdf_IncrementBuffer(*buffer_length, derived_size, ctx->mac_size);
        }

        /* Handle the last key. */
        derived_size = kbkdf_GetDerivedKeySize(params->pAdditionalDerivedKeys + offset);

        *output_bitlen += derived_size;
        *buffer_length = kbkdf_IncrementBuffer(*buffer_length, derived_size, ctx->mac_size);

        /* Pointer to the DKM method parameter. Note that this implicit cast
         * is safe since we've assumed we've been validated by
         * kbkdf_ValidateParameters(...). When kdm_param is NULL, we don't
         * use the output_bitlen parameter. */
        CK_SP800_108_DKM_LENGTH_FORMAT_PTR dkm_param = kbkdf_FindParameter(params, CK_SP800_108_DKM_LENGTH);
        if (dkm_param != NULL) {
            if (dkm_param->dkmLengthMethod == CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS) {
                *output_bitlen = *buffer_length;
            }
        }
    }

    /* Note that keySize is the size in bytes and ctx->mac_size is also
     * the size in bytes. However, output_bitlen needs to be in bits, so
     * multiply by 8 here. */
    *output_bitlen *= 8;

    return CKR_OK;
}

static CK_RV
kbkdf_CalculateIterations(CK_MECHANISM_TYPE mech, const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, size_t buffer_length, PRUint32 *num_iterations)
{
    CK_SP800_108_COUNTER_FORMAT_PTR param_ptr = NULL;
    PRUint64 iteration_count;
    PRUint64 r = 32;

    /* We need to know how many full iterations are required. This is done
     * by rounding up the division of the PRF length into buffer_length.
     * However, we're not guaranteed that the last output is a full PRF
     * invocation, so handle that here. */
    iteration_count = buffer_length + (ctx->mac_size - 1);
    iteration_count = iteration_count / ctx->mac_size;

    /* NIST SP800-108, section 5.1, process step #2:
     *
     *      if n > 2^r - 1, then indicate an error and stop.
     *
     * In non-counter mode KDFs, r is set at 32, leaving behavior
     * under-defined when the optional counter is included but fewer than
     * 32 bits. This implementation assumes r is 32, but if the counter
     * parameter is included, validates it against that. In counter-mode
     * KDFs, this is in the ITERATION_VARIABLE parameter; in feedback- or
     * pipeline-mode KDFs, this is in the COUNTER parameter.
     *
     * This is consistent with the supplied sample CAVP tests; none reuses the
     * same counter value. In some configurations, this could result in
     * duplicated KDF output. We seek to avoid that from happening.
     */
    if (IS_COUNTER(mech)) {
        param_ptr = kbkdf_FindParameter(params, CK_SP800_108_ITERATION_VARIABLE);

        /* Validated by kbkdf_ValidateParameters(...) above. */
        PR_ASSERT(param_ptr != NULL);

        r = ((CK_SP800_108_COUNTER_FORMAT_PTR)param_ptr)->ulWidthInBits;
    } else {
        param_ptr = kbkdf_FindParameter(params, CK_SP800_108_COUNTER);

        /* Not guaranteed to exist, hence the default value of r=32. */
        if (param_ptr != NULL) {
            r = ((CK_SP800_108_COUNTER_FORMAT_PTR)param_ptr)->ulWidthInBits;
        }
    }

    if (iteration_count >= (1ull << r) || r > 32) {
        return CKR_MECHANISM_PARAM_INVALID;
    }

    *num_iterations = (PRUint32)iteration_count;

    return CKR_OK;
}

static CK_RV
kbkdf_AddParameters(CK_MECHANISM_TYPE mech, sftk_MACCtx *ctx, const CK_SP800_108_KDF_PARAMS *params, PRUint32 counter, PRUint64 length, const unsigned char *chaining_prf, size_t chaining_prf_len, CK_PRF_DATA_TYPE exclude)
{
    size_t offset = 0;
    CK_RV ret = CKR_OK;

    for (offset = 0; offset < params->ulNumberOfDataParams; offset++) {
        CK_PRF_DATA_PARAM_PTR param = params->pDataParams + offset;

        if (param->type == exclude) {
            /* Necessary for Double Pipeline mode: when constructing the IV,
             * we skip the  optional counter. */
            continue;
        }

        switch (param->type) {
            case CK_SP800_108_ITERATION_VARIABLE: {
                /* When present in COUNTER mode, this signifies adding the counter
                 * variable to the PRF. Otherwise, it signifies the chaining
                 * value for other KDF modes. */
                if (IS_COUNTER(mech)) {
                    CK_SP800_108_COUNTER_FORMAT_PTR counter_format = (CK_SP800_108_COUNTER_FORMAT_PTR)param->pValue;
                    CK_BYTE buffer[sizeof(PRUint64)];
                    CK_ULONG num_bytes;
                    sftk_EncodeInteger(counter, counter_format->ulWidthInBits, counter_format->bLittleEndian, buffer, &num_bytes);
                    ret = sftk_MAC_Update(ctx, buffer, num_bytes);
                } else {
                    ret = sftk_MAC_Update(ctx, chaining_prf, chaining_prf_len);
                }
                break;
            }
            case CK_SP800_108_COUNTER: {
                /* Only present in the case when not using COUNTER mode. */
                PR_ASSERT(!IS_COUNTER(mech));

                /* We should've already validated that this parameter is of
                 * type COUNTER_FORMAT. */
                CK_SP800_108_COUNTER_FORMAT_PTR counter_format = (CK_SP800_108_COUNTER_FORMAT_PTR)param->pValue;
                CK_BYTE buffer[sizeof(PRUint64)];
                CK_ULONG num_bytes;
                sftk_EncodeInteger(counter, counter_format->ulWidthInBits, counter_format->bLittleEndian, buffer, &num_bytes);
                ret = sftk_MAC_Update(ctx, buffer, num_bytes);
                break;
            }
            case CK_SP800_108_BYTE_ARRAY:
                ret = sftk_MAC_Update(ctx, (CK_BYTE_PTR)param->pValue, param->ulValueLen);
                break;
            case CK_SP800_108_DKM_LENGTH: {
                /* We've already done the hard work of calculating the length in
                 * the kbkdf_CalculateIterations function; we merely need to add
                 * the length to the desired point in the input stream. */
                CK_SP800_108_DKM_LENGTH_FORMAT_PTR length_format = (CK_SP800_108_DKM_LENGTH_FORMAT_PTR)param->pValue;
                CK_BYTE buffer[sizeof(PRUint64)];
                CK_ULONG num_bytes;
                sftk_EncodeInteger(length, length_format->ulWidthInBits, length_format->bLittleEndian, buffer, &num_bytes);
                ret = sftk_MAC_Update(ctx, buffer, num_bytes);
                break;
            }
            default:
                /* This should've been caught by kbkdf_ValidateParameters(...). */
                PR_ASSERT(PR_FALSE);
                return CKR_MECHANISM_PARAM_INVALID;
        }

        if (ret != CKR_OK) {
            return ret;
        }
    }

    return CKR_OK;
}

CK_RV
kbkdf_SaveKey(SFTKObject *key, unsigned char *key_buffer, unsigned int key_len)
{
    return sftk_forceAttribute(key, CKA_VALUE, key_buffer, key_len);
}

CK_RV
kbkdf_CreateKey(CK_MECHANISM_TYPE kdf_mech, CK_SESSION_HANDLE hSession, CK_DERIVED_KEY_PTR derived_key, SFTKObject **ret_key)
{
    /* Largely duplicated from NSC_DeriveKey(...) */
    CK_RV ret = CKR_HOST_MEMORY;
    SFTKObject *key = NULL;
    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    size_t offset = 0;

    /* Slot should be non-NULL because NSC_DeriveKey(...) has already
     * performed a sftk_SlotFromSessionHandle(...) call on this session
     * handle. However, Coverity incorrectly flagged this (see 1607955). */
    PR_ASSERT(slot != NULL);
    PR_ASSERT(ret_key != NULL);
    PR_ASSERT(derived_key != NULL);
    PR_ASSERT(derived_key->phKey != NULL);

    if (slot == NULL) {
        return CKR_SESSION_HANDLE_INVALID;
    }

    /* Create the new key object for this additional derived key. */
    key = sftk_NewObject(slot);
    if (key == NULL) {
        return CKR_HOST_MEMORY;
    }

    /* Setup the key from the provided template. */
    for (offset = 0; offset < derived_key->ulAttributeCount; offset++) {
        ret = sftk_AddAttributeType(key, sftk_attr_expand(derived_key->pTemplate + offset));
        if (ret != CKR_OK) {
            sftk_FreeObject(key);
            return ret;
        }
    }

    /* When using the CKM_SP800_* series of mechanisms, the result must be a
     * secret key, so its contents can be adequately protected in FIPS mode.
     * However, when using the special CKM_NSS_SP800_*_DERIVE_DATA series, the
     * contents need not be protected, so we set CKO_DATA on these "keys". */
    CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
    if (DOES_DERIVE_DATA(kdf_mech)) {
        classType = CKO_DATA;
    }

    ret = sftk_forceAttribute(key, CKA_CLASS, &classType, sizeof(classType));
    if (ret != CKR_OK) {
        sftk_FreeObject(key);
        return ret;
    }

    *ret_key = key;
    return CKR_OK;
}

CK_RV
kbkdf_FinalizeKey(CK_SESSION_HANDLE hSession, CK_DERIVED_KEY_PTR derived_key, SFTKObject *key)
{
    /* Largely duplicated from NSC_DeriveKey(...) */
    CK_RV ret = CKR_HOST_MEMORY;
    SFTKSession *session = NULL;

    PR_ASSERT(derived_key != NULL && key != NULL);

    SFTKSessionObject *sessionForKey = sftk_narrowToSessionObject(key);
    PR_ASSERT(sessionForKey != NULL);
    sessionForKey->wasDerived = PR_TRUE;

    session = sftk_SessionFromHandle(hSession);

    /* Session should be non-NULL because NSC_DeriveKey(...) has already
     * performed a sftk_SessionFromHandle(...) call on this session handle. */
    PR_ASSERT(session != NULL);

    ret = sftk_handleObject(key, session);
    if (ret != CKR_OK) {
        goto done;
    }

    *(derived_key->phKey) = key->handle;

done:
    /* Guaranteed that key != NULL */
    sftk_FreeObject(key);

    /* Doesn't do anything. */
    if (session) {
        sftk_FreeSession(session);
    }

    return ret;
}

CK_RV
kbkdf_SaveKeys(CK_MECHANISM_TYPE mech, CK_SESSION_HANDLE hSession, CK_SP800_108_KDF_PARAMS_PTR params, unsigned char *output_buffer, size_t buffer_len, size_t prf_length, SFTKObject *ret_key, CK_ULONG ret_key_size)
{
    CK_RV ret;
    size_t key_offset = 0;
    size_t buffer_offset = 0;

    PR_ASSERT(output_buffer != NULL && buffer_len > 0 && ret_key != NULL);

    /* First place key material into the main key. */
    ret = kbkdf_SaveKey(ret_key, output_buffer + buffer_offset, ret_key_size);
    if (ret != CKR_OK) {
        return ret;
    }

    /* Then increment the offset based on PKCS#11 additional key guidelines:
     * no two keys may share the key stream from the same PRF invocation. */
    buffer_offset = kbkdf_IncrementBuffer(buffer_offset, ret_key_size, prf_length);

    if (params->ulAdditionalDerivedKeys > 0) {
        /* Note that the following code is technically incorrect: PKCS#11 v3.0
         * says that _no_ key should be set in the event of failure to derive
         * _any_ key. */
        for (key_offset = 0; key_offset < params->ulAdditionalDerivedKeys; key_offset++) {
            CK_DERIVED_KEY_PTR derived_key = params->pAdditionalDerivedKeys + key_offset;
            SFTKObject *key_obj = NULL;
            size_t key_size = kbkdf_GetDerivedKeySize(derived_key);

            /* Create a new internal key object for this derived key. */
            ret = kbkdf_CreateKey(mech, hSession, derived_key, &key_obj);
            if (ret != CKR_OK) {
                *(derived_key->phKey) = CK_INVALID_HANDLE;
                return ret;
            }

            /* Save the underlying key bytes to the key object. */
            ret = kbkdf_SaveKey(key_obj, output_buffer + buffer_offset, key_size);
            if (ret != CKR_OK) {
                /* When kbkdf_CreateKey(...) exits with an error, it will free
                 * the constructed key object. kbkdf_FinalizeKey(...) also
                 * always frees the key object. In the unlikely event that
                 * kbkdf_SaveKey(...) _does_ fail, we thus need to free it
                 * manually. */
                sftk_FreeObject(key_obj);
                *(derived_key->phKey) = CK_INVALID_HANDLE;
                return ret;
            }

            /* Handle the increment. */
            buffer_offset = kbkdf_IncrementBuffer(buffer_offset, key_size, prf_length);

            /* Finalize this key. */
            ret = kbkdf_FinalizeKey(hSession, derived_key, key_obj);
            if (ret != CKR_OK) {
                *(derived_key->phKey) = CK_INVALID_HANDLE;
                return ret;
            }
        }
    }

    return CKR_OK;
}

/* [ section: KDFs ] */

static CK_RV
kbkdf_CounterRaw(const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, unsigned char *ret_buffer, size_t buffer_length, PRUint64 output_bitlen)
{
    CK_RV ret = CKR_OK;

    /* Counter variable for this KDF instance. */
    PRUint32 counter;

    /* Number of iterations required of this PRF necessary to reach the
     * desired output length. */
    PRUint32 num_iterations;

    /* Offset in ret_buffer that we're at. */
    size_t buffer_offset = 0;

    /* Size of this block, in bytes. Defaults to ctx->mac_size except on
     * the last iteration where it could be a partial block. */
    size_t block_size = ctx->mac_size;

    /* Calculate the number of iterations required based on the size of the
     * output buffer. */
    ret = kbkdf_CalculateIterations(CKM_SP800_108_COUNTER_KDF, params, ctx, buffer_length, &num_iterations);
    if (ret != CKR_OK) {
        return ret;
    }

    /*
     * 5.1 - [ KDF in Counter Mode ]
     *
     * Fixed values:
     *      1. h - the length of the PRF in bits (ctx->mac_size)
     *      2. r - the length of the binary representation of the counter i
     *          (params[k: params[k].type == CK_SP800_108_ITERATION_VARIABLE:].data->ulWidthInBits)
     * Input:
     *      1. K_I - the key for the PRF (base_key)
     *      2. label - a binary data field, usually before the separator. Optional.
     *      3. context - a binary data field, usually after the separator. Optional.
     *      4. L - length of the output in bits (output_bitlen)
     *
     * Process:
     *      1. n := ceil(L / h) (num_iterations)
     *      2. if n > 2^r - 1, then indicate an error and stop
     *      3. result(0) = NULL
     *      4. for i = 1 to n, do
     *          a. K(i) = PRF(K_I, [i]_2 || Label || 0x00 || Context || [L]_2)
     *          b. result(i) := result(i - 1) || K(i).
     *      5. return K_O := the leftmost L bits of result(n).
     */
    for (counter = 1; counter <= num_iterations; counter++) {
        if (counter == num_iterations) {
            block_size = buffer_length - buffer_offset;

            /* Assumption: if we've validated our arguments correctly, this
             * should always be true. */
            PR_ASSERT(block_size <= ctx->mac_size);
        }

        /* Add all parameters required by this instance of the KDF to the
         * input stream of the underlying PRF. */
        ret = kbkdf_AddParameters(CKM_SP800_108_COUNTER_KDF, ctx, params, counter, output_bitlen, NULL, 0 /* chaining_prf output */, 0 /* exclude */);
        if (ret != CKR_OK) {
            return ret;
        }

        /* Finalize this iteration of the PRF. */
        ret = sftk_MAC_Finish(ctx, ret_buffer + buffer_offset, NULL, block_size);
        if (ret != CKR_OK) {
            return ret;
        }

        /* Increment our position in the key material. */
        buffer_offset += block_size;

        if (counter < num_iterations) {
            /* Reset the underlying PRF for the next iteration. Only do this
             * when we have a next iteration since it isn't necessary to do
             * either before the first iteration (MAC is already initialized)
             * or after the last iteration (we won't be called again). */
            ret = sftk_MAC_Reset(ctx);
            if (ret != CKR_OK) {
                return ret;
            }
        }
    }

    return CKR_OK;
}

static CK_RV
kbkdf_FeedbackRaw(const CK_SP800_108_KDF_PARAMS *params, const unsigned char *initial_value, CK_ULONG initial_value_length, sftk_MACCtx *ctx, unsigned char *ret_buffer, size_t buffer_length, PRUint64 output_bitlen)
{
    CK_RV ret = CKR_OK;

    /* Counter variable for this KDF instance. */
    PRUint32 counter;

    /* Number of iterations required of this PRF necessary to reach the
     * desired output length. */
    PRUint32 num_iterations;

    /* Offset in ret_buffer that we're at. */
    size_t buffer_offset = 0;

    /* Size of this block, in bytes. Defaults to ctx->mac_size except on
     * the last iteration where it could be a partial block. */
    size_t block_size = ctx->mac_size;

    /* The last PRF invocation and/or the initial value; used for feedback
     * chaining in this KDF. Note that we have to make it large enough to
     * fit the output of the PRF, but we can delay its actual creation until
     * the first PRF invocation. Until then, point to the IV value. */
    unsigned char *chaining_value = (unsigned char *)initial_value;

    /* Size of the chaining value discussed above. Defaults to the size of
     * the IV value. */
    size_t chaining_length = initial_value_length;

    /* Calculate the number of iterations required based on the size of the
     * output buffer. */
    ret = kbkdf_CalculateIterations(CKM_SP800_108_FEEDBACK_KDF, params, ctx, buffer_length, &num_iterations);
    if (ret != CKR_OK) {
        goto finish;
    }

    /*
     * 5.2 - [ KDF in Feedback Mode ]
     *
     * Fixed values:
     *      1. h - the length of the PRF in bits (ctx->mac_size)
     *      2. r - the length of the binary representation of the counter i
     *          (params[k: params[k].type == CK_SP800_108_OPTIONAL_COUNTER:].data->ulWidthInBits)
     *          Note that it is only specified when the optional counter is requested.
     * Input:
     *      1. K_I - the key for the PRF (base_key)
     *      2. label - a binary data field, usually before the separator. Optional.
     *      3. context - a binary data field, usually after the separator. Optional.
     *      4. IV - a binary data field, initial PRF value. (params->pIV)
     *      5. L - length of the output in bits (output_bitlen)
     *
     * Process:
     *      1. n := ceil(L / h) (num_iterations)
     *      2. if n > 2^32 - 1, then indicate an error and stop
     *      3. result(0) = NULL, K(0) := IV (chaining_value)
     *      4. for i = 1 to n, do
     *          a. K(i) = PRF(K_I, K(i-1) {|| [i]_2} || Label || 0x00 || Context || [L]_2)
     *          b. result(i) := result(i - 1) || K(i).
     *      5. return K_O := the leftmost L bits of result(n).
     */
    for (counter = 1; counter <= num_iterations; counter++) {
        if (counter == num_iterations) {
            block_size = buffer_length - buffer_offset;

            /* Assumption: if we've validated our arguments correctly, this
             * should always be true. */
            PR_ASSERT(block_size <= ctx->mac_size);
        }

        /* Add all parameters required by this instance of the KDF to the
         * input stream of the underlying PRF. */
        ret = kbkdf_AddParameters(CKM_SP800_108_FEEDBACK_KDF, ctx, params, counter, output_bitlen, chaining_value, chaining_length, 0 /* exclude */);
        if (ret != CKR_OK) {
            goto finish;
        }

        if (counter == 1) {
            /* On the first iteration, chaining_value points to the IV from
             * the caller and chaining_length is the length of that IV. We
             * now need to allocate a buffer of suitable length to store the
             * MAC output. */
            chaining_value = PORT_ZNewArray(unsigned char, ctx->mac_size);
            chaining_length = ctx->mac_size;

            if (chaining_value == NULL) {
                ret = CKR_HOST_MEMORY;
                goto finish;
            }
        }

        /* Finalize this iteration of the PRF. Unlike other KDF forms, we
         * first save this to the chaining value so that we can reuse it
         * in the next iteration before copying the necessary length to
         * the output buffer. */
        ret = sftk_MAC_Finish(ctx, chaining_value, NULL, chaining_length);
        if (ret != CKR_OK) {
            goto finish;
        }

        /* Save as much of the chaining value as we need for output. */
        PORT_Memcpy(ret_buffer + buffer_offset, chaining_value, block_size);

        /* Increment our position in the key material. */
        buffer_offset += block_size;

        if (counter < num_iterations) {
            /* Reset the underlying PRF for the next iteration. Only do this
             * when we have a next iteration since it isn't necessary to do
             * either before the first iteration (MAC is already initialized)
             * or after the last iteration (we won't be called again). */
            ret = sftk_MAC_Reset(ctx);
            if (ret != CKR_OK) {
                goto finish;
            }
        }
    }

finish:
    if (chaining_value != initial_value && chaining_value != NULL) {
        PORT_ZFree(chaining_value, chaining_length);
    }

    return ret;
}

static CK_RV
kbkdf_PipelineRaw(const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, unsigned char *ret_buffer, size_t buffer_length, PRUint64 output_bitlen)
{
    CK_RV ret = CKR_OK;

    /* Counter variable for this KDF instance. */
    PRUint32 counter;

    /* Number of iterations required of this PRF necessary to reach the
     * desired output length. */
    PRUint32 num_iterations;

    /* Offset in ret_buffer that we're at. */
    size_t buffer_offset = 0;

    /* Size of this block, in bytes. Defaults to ctx->mac_size except on
     * the last iteration where it could be a partial block. */
    size_t block_size = ctx->mac_size;

    /* The last PRF invocation. This is used for the first of the double
     * PRF invocations this KDF is named after. This defaults to NULL,
     * signifying that we have to calculate the initial value from params;
     * when non-NULL, we directly add only this value to the PRF. */
    unsigned char *chaining_value = NULL;

    /* Size of the chaining value discussed above. Defaults to 0. */
    size_t chaining_length = 0;

    /* Calculate the number of iterations required based on the size of the
     * output buffer. */
    ret = kbkdf_CalculateIterations(CKM_SP800_108_DOUBLE_PIPELINE_KDF, params, ctx, buffer_length, &num_iterations);
    if (ret != CKR_OK) {
        goto finish;
    }

    /*
     * 5.3 - [ KDF in Double-Pipeline Iteration Mode ]
     *
     * Fixed values:
     *      1. h - the length of the PRF in bits (ctx->mac_size)
     *      2. r - the length of the binary representation of the counter i
     *          (params[k: params[k].type == CK_SP800_108_OPTIONAL_COUNTER:].data->ulWidthInBits)
     *          Note that it is only specified when the optional counter is requested.
     * Input:
     *      1. K_I - the key for the PRF (base_key)
     *      2. label - a binary data field, usually before the separator. Optional.
     *      3. context - a binary data field, usually after the separator. Optional.
     *      4. L - length of the output in bits (output_bitlen)
     *
     * Process:
     *      1. n := ceil(L / h) (num_iterations)
     *      2. if n > 2^32 - 1, then indicate an error and stop
     *      3. result(0) = NULL
     *      4. A(0) := IV := Label || 0x00 || Context || [L]_2
     *      5. for i = 1 to n, do
     *          a. A(i) := PRF(K_I, A(i-1))
     *          b. K(i) := PRF(K_I, A(i) {|| [i]_2} || Label || 0x00 || Context || [L]_2
     *          c. result(i) := result(i-1) || K(i)
     *      6. return K_O := the leftmost L bits of result(n).
     */
    for (counter = 1; counter <= num_iterations; counter++) {
        if (counter == num_iterations) {
            block_size = buffer_length - buffer_offset;

            /* Assumption: if we've validated our arguments correctly, this
             * should always be true. */
            PR_ASSERT(block_size <= ctx->mac_size);
        }

        /* ===== First pipeline: construct A(i) ===== */
        if (counter == 1) {
            /* On the first iteration, we have no chaining value so specify
             * NULL for the pointer and 0 for the length, and exclude the
             * optional counter if it exists. This is what NIST specifies as
             * the IV for the KDF. */
            ret = kbkdf_AddParameters(CKM_SP800_108_DOUBLE_PIPELINE_KDF, ctx, params, counter, output_bitlen, NULL, 0, CK_SP800_108_OPTIONAL_COUNTER);
            if (ret != CKR_OK) {
                goto finish;
            }

            /* Allocate the chaining value so we can save the PRF output. */
            chaining_value = PORT_ZNewArray(unsigned char, ctx->mac_size);
            chaining_length = ctx->mac_size;
            if (chaining_value == NULL) {
                ret = CKR_HOST_MEMORY;
                goto finish;
            }
        } else {
            /* On all other iterations, the next stage of the first pipeline
             * comes directly from this stage. */
            ret = sftk_MAC_Update(ctx, chaining_value, chaining_length);
            if (ret != CKR_OK) {
                goto finish;
            }
        }

        /* Save the PRF output to chaining_value for use in the second
         * pipeline. */
        ret = sftk_MAC_Finish(ctx, chaining_value, NULL, chaining_length);
        if (ret != CKR_OK) {
            goto finish;
        }

        /* Reset the PRF so we can reuse it for the second pipeline. */
        ret = sftk_MAC_Reset(ctx);
        if (ret != CKR_OK) {
            goto finish;
        }

        /* ===== Second pipeline: construct K(i) ===== */

        /* Add all parameters required by this instance of the KDF to the
         * input stream of the underlying PRF. Note that this includes the
         * chaining value we calculated from the previous pipeline stage. */
        ret = kbkdf_AddParameters(CKM_SP800_108_FEEDBACK_KDF, ctx, params, counter, output_bitlen, chaining_value, chaining_length, 0 /* exclude */);
        if (ret != CKR_OK) {
            goto finish;
        }

        /* Finalize this iteration of the PRF directly to the output buffer.
         * Unlike Feedback mode, this pipeline doesn't influence the previous
         * stage. */
        ret = sftk_MAC_Finish(ctx, ret_buffer + buffer_offset, NULL, block_size);
        if (ret != CKR_OK) {
            goto finish;
        }

        /* Increment our position in the key material. */
        buffer_offset += block_size;

        if (counter < num_iterations) {
            /* Reset the underlying PRF for the next iteration. Only do this
             * when we have a next iteration since it isn't necessary to do
             * either before the first iteration (MAC is already initialized)
             * or after the last iteration (we won't be called again). */
            ret = sftk_MAC_Reset(ctx);
            if (ret != CKR_OK) {
                goto finish;
            }
        }
    }

finish:
    PORT_ZFree(chaining_value, chaining_length);

    return ret;
}

static CK_RV
kbkdf_RawDispatch(CK_MECHANISM_TYPE mech,
                  const CK_SP800_108_KDF_PARAMS *kdf_params,
                  const CK_BYTE *initial_value,
                  CK_ULONG initial_value_length,
                  SFTKObject *prf_key, const unsigned char *prf_key_bytes,
                  unsigned int prf_key_length, unsigned char **out_key_bytes,
                  size_t *out_key_length, unsigned int *mac_size,
                  CK_ULONG ret_key_size)
{
    CK_RV ret;
    /* Context for our underlying PRF function.
     *
     * Zeroing context required unconditional call of sftk_MAC_Destroy.
     */
    sftk_MACCtx ctx = { 0 };

    /* We need one buffers large enough to fit the entire KDF key stream for
     * all iterations of the PRF. This needs only include to the end of the
     * last key, so it isn't an even multiple of the PRF output size. */
    unsigned char *output_buffer = NULL;

    /* Size of the above buffer, in bytes. Note that this is technically
     * separate from the below output_bitlen variable due to the presence
     * of additional derived keys. See commentary in kbkdf_CalculateLength.
     */
    size_t buffer_length = 0;

    /* While NIST specifies a maximum length (in bits) for the counter, they
     * don't for the maximum length. It is unlikely, but theoretically
     * possible for output of the PRF to exceed 32 bits while keeping the
     * counter under 2^32. Thus, use a 64-bit variable for the maximum
     * output length.
     *
     * It is unlikely any caller will request this much data in practice.
     * 2^32 invocations of the PRF (for a 512-bit PRF) would be 256GB of
     * data in the KDF key stream alone. The bigger limit is the number of
     * and size of keys (again, 2^32); this could easily exceed 256GB when
     * counting the backing softoken key, the key data, template data, and
     * the input parameters to this KDF.
     *
     * This is the L parameter in NIST SP800-108.
     */
    PRUint64 output_bitlen = 0;

    /* First validate our passed input parameters against PKCS#11 v3.0
     * and NIST SP800-108 requirements. */
    ret = kbkdf_ValidateParameters(mech, kdf_params, ret_key_size);
    if (ret != CKR_OK) {
        goto finish;
    }

    /* Initialize the underlying PRF state. */
    if (prf_key) {
        ret = sftk_MAC_Init(&ctx, kdf_params->prfType, prf_key);
    } else {
        ret = sftk_MAC_InitRaw(&ctx, kdf_params->prfType, prf_key_bytes,
                               prf_key_length, PR_TRUE);
    }
    if (ret != CKR_OK) {
        goto finish;
    }

    /* Compute the size of our output buffer based on passed parameters and
     * the output size of the underlying PRF. */
    ret = kbkdf_CalculateLength(kdf_params, &ctx, ret_key_size, &output_bitlen, &buffer_length);
    if (ret != CKR_OK) {
        goto finish;
    }

    /* Allocate memory for the PRF output */
    output_buffer = PORT_ZNewArray(unsigned char, buffer_length);
    if (output_buffer == NULL) {
        ret = CKR_HOST_MEMORY;
        goto finish;
    }

    /* Call into the underlying KDF */
    switch (mech) {
        case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA: /* fall through */
        case CKM_SP800_108_COUNTER_KDF:
            ret = kbkdf_CounterRaw(kdf_params, &ctx, output_buffer, buffer_length, output_bitlen);
            break;
        case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA: /* fall through */
        case CKM_SP800_108_FEEDBACK_KDF:
            ret = kbkdf_FeedbackRaw(kdf_params, initial_value, initial_value_length, &ctx, output_buffer, buffer_length, output_bitlen);
            break;
        case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA: /* fall through */
        case CKM_SP800_108_DOUBLE_PIPELINE_KDF:
            ret = kbkdf_PipelineRaw(kdf_params, &ctx, output_buffer, buffer_length, output_bitlen);
            break;
        default:
            /* Shouldn't happen unless NIST introduces a new KBKDF type. */
            PR_ASSERT(PR_FALSE);
            ret = CKR_FUNCTION_FAILED;
    }

    /* Validate the above KDF succeeded. */
    if (ret != CKR_OK) {
        goto finish;
    }

    *out_key_bytes = output_buffer;
    *out_key_length = buffer_length;
    *mac_size = ctx.mac_size;

    output_buffer = NULL; /* returning the buffer, don't zero and free it */

finish:
    PORT_ZFree(output_buffer, buffer_length);

    /* Free the PRF. This should handle clearing all sensitive information. */
    sftk_MAC_Destroy(&ctx, PR_FALSE);
    return ret;
}

/* [ section: PKCS#11 entry ] */

CK_RV
kbkdf_Dispatch(CK_MECHANISM_TYPE mech, CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, SFTKObject *prf_key, SFTKObject *ret_key, CK_ULONG ret_key_size)
{
    /* This handles boilerplate common to all KBKDF types. Instead of placing
     * this in pkcs11c.c, place it here to reduce clutter. */

    CK_RV ret;

    /* Assumptions about our calling environment. */
    PR_ASSERT(pMechanism != NULL && prf_key != NULL && ret_key != NULL);

    /* Validate that the caller passed parameters. */
    if (pMechanism->pParameter == NULL) {
        return CKR_MECHANISM_PARAM_INVALID;
    }

    /* Create a common set of parameters to use for all KDF types. This
     * separates out the KDF parameters from the Feedback-specific IV,
     * allowing us to use a common type for all calls. */
    CK_SP800_108_KDF_PARAMS kdf_params = { 0 };
    CK_BYTE_PTR initial_value = NULL;
    CK_ULONG initial_value_length = 0;
    unsigned char *output_buffer = NULL;
    size_t buffer_length = 0;
    unsigned int mac_size = 0;

    /* Split Feedback-specific IV from remaining KDF parameters. */
    ret = kbkdf_LoadParameters(mech, pMechanism, &kdf_params, &initial_value, &initial_value_length);
    if (ret != CKR_OK) {
        goto finish;
    }
    /* let rawDispatch handle the rest. We split this out so we could
     * handle the POST test without accessing pkcs #11 objects. */
    ret = kbkdf_RawDispatch(mech, &kdf_params, initial_value,
                            initial_value_length, prf_key, NULL, 0,
                            &output_buffer, &buffer_length, &mac_size,
                            ret_key_size);
    if (ret != CKR_OK) {
        goto finish;
    }

    /* Write the output of the PRF into the appropriate keys. */
    ret = kbkdf_SaveKeys(mech, hSession, &kdf_params, output_buffer, buffer_length, mac_size, ret_key, ret_key_size);
    if (ret != CKR_OK) {
        goto finish;
    }

finish:
    PORT_ZFree(output_buffer, buffer_length);

    return ret;
}

struct sftk_SP800_Test_struct {
    CK_MECHANISM_TYPE mech;
    CK_SP800_108_KDF_PARAMS kdf_params;
    unsigned int expected_mac_size;
    unsigned int ret_key_length;
    const unsigned char expected_key_bytes[64];
};

static const CK_SP800_108_COUNTER_FORMAT counter_32 = { 0, 32 };
static const CK_PRF_DATA_PARAM counter_32_data =
    { CK_SP800_108_ITERATION_VARIABLE, (CK_VOID_PTR)&counter_32, sizeof(counter_32) };

#ifdef NSS_FULL_POST
static const CK_SP800_108_COUNTER_FORMAT counter_16 = { 0, 16 };
static const CK_PRF_DATA_PARAM counter_16_data =
    { CK_SP800_108_ITERATION_VARIABLE, (CK_VOID_PTR)&counter_16, sizeof(counter_16) };
static const CK_PRF_DATA_PARAM counter_null_data =
    { CK_SP800_108_ITERATION_VARIABLE, NULL, 0 };
#endif

static const struct sftk_SP800_Test_struct sftk_SP800_Tests[] =
    {
#ifdef NSS_FULL_POST
      {
          CKM_SP800_108_COUNTER_KDF,
          { CKM_AES_CMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_16_data, 0, NULL },
          16,
          64,
          { 0x7b, 0x1c, 0xe7, 0xf3, 0x14, 0x67, 0x15, 0xdd,
            0xde, 0x0c, 0x09, 0x46, 0x3f, 0x47, 0x7b, 0xa6,
            0xb8, 0xba, 0x40, 0x07, 0x7c, 0xe3, 0x19, 0x53,
            0x26, 0xac, 0x4c, 0x2e, 0x2b, 0x37, 0x41, 0xe4,
            0x1b, 0x01, 0x3f, 0x2f, 0x2d, 0x16, 0x95, 0xee,
            0xeb, 0x7e, 0x72, 0x7d, 0xa4, 0xab, 0x2e, 0x67,
            0x1d, 0xef, 0x6f, 0xa2, 0xc6, 0xee, 0x3c, 0xcf,
            0xef, 0x88, 0xfd, 0x5c, 0x1d, 0x7b, 0xa0, 0x5a },
      },
      {
          CKM_SP800_108_COUNTER_KDF,
          { CKM_SHA384_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_32_data, 0, NULL },
          48,
          64,
          { 0xe6, 0x62, 0xa4, 0x32, 0x5c, 0xe4, 0xc2, 0x28,
            0x73, 0x8a, 0x5d, 0x94, 0xe7, 0x05, 0xe0, 0x5a,
            0x71, 0x61, 0xb2, 0x3c, 0x51, 0x28, 0x03, 0x1d,
            0xa7, 0xf5, 0x10, 0x83, 0x34, 0xdb, 0x11, 0x73,
            0x92, 0xa6, 0x79, 0x74, 0x81, 0x5d, 0x22, 0x7e,
            0x8d, 0xf2, 0x59, 0x14, 0x56, 0x60, 0xcf, 0xb2,
            0xb3, 0xfd, 0x46, 0xfd, 0x9b, 0x74, 0xfe, 0x4a,
            0x09, 0x30, 0x4a, 0xdf, 0x07, 0x43, 0xfe, 0x85 },
      },
      {
          CKM_SP800_108_COUNTER_KDF,
          { CKM_SHA512_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_32_data, 0, NULL },
          64,
          64,
          { 0xb0, 0x78, 0x36, 0xe1, 0x15, 0xd6, 0xf0, 0xac,
            0x68, 0x7b, 0x42, 0xd3, 0xb6, 0x82, 0x51, 0xad,
            0x95, 0x0a, 0x69, 0x88, 0x84, 0xc2, 0x2e, 0x07,
            0x34, 0x62, 0x8d, 0x42, 0x72, 0x0f, 0x22, 0xe6,
            0xd5, 0x7f, 0x80, 0x15, 0xe6, 0x84, 0x00, 0x65,
            0xef, 0x64, 0x77, 0x29, 0xd6, 0x3b, 0xc7, 0x9a,
            0x15, 0x6d, 0x36, 0xf3, 0x96, 0xc9, 0x14, 0x3f,
            0x2d, 0x4a, 0x7c, 0xdb, 0xc3, 0x6c, 0x3d, 0x6a },
      },
      {
          CKM_SP800_108_FEEDBACK_KDF,
          { CKM_AES_CMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          16,
          64,
          { 0xc0, 0xa0, 0x23, 0x96, 0x16, 0x4d, 0xd6, 0xbd,
            0x2a, 0x75, 0x8e, 0x72, 0xf5, 0xc3, 0xa0, 0xb8,
            0x78, 0x83, 0x15, 0x21, 0x34, 0xd3, 0xd8, 0x71,
            0xc9, 0xe7, 0x4b, 0x20, 0xb7, 0x65, 0x5b, 0x13,
            0xbc, 0x85, 0x54, 0xe3, 0xb6, 0xee, 0x73, 0xd5,
            0xf2, 0xa0, 0x94, 0x1a, 0x79, 0x66, 0x3b, 0x1e,
            0x67, 0x3e, 0x69, 0xa4, 0x12, 0x40, 0xa9, 0xda,
            0x8d, 0x14, 0xb1, 0xce, 0xf1, 0x4b, 0x79, 0x4e },
      },
      {
          CKM_SP800_108_FEEDBACK_KDF,
          { CKM_SHA256_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          32,
          64,
          { 0x99, 0x9b, 0x08, 0x79, 0x14, 0x2e, 0x58, 0x34,
            0xd7, 0x92, 0xa7, 0x7e, 0x7f, 0xc2, 0xf0, 0x34,
            0xa3, 0x4e, 0x33, 0xf0, 0x63, 0x95, 0x2d, 0xad,
            0xbf, 0x3b, 0xcb, 0x6d, 0x4e, 0x07, 0xd9, 0xe9,
            0xbd, 0xbd, 0x77, 0x54, 0xe1, 0xa3, 0x36, 0x26,
            0xcd, 0xb1, 0xf9, 0x2d, 0x80, 0x68, 0xa2, 0x01,
            0x4e, 0xbf, 0x35, 0xec, 0x65, 0xae, 0xfd, 0x71,
            0xa6, 0xd7, 0x62, 0x26, 0x2c, 0x3f, 0x73, 0x63 },
      },
      {
          CKM_SP800_108_FEEDBACK_KDF,
          { CKM_SHA384_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          48,
          64,
          { 0xc8, 0x7a, 0xf8, 0xd9, 0x6b, 0x90, 0x82, 0x35,
            0xea, 0xf5, 0x2c, 0x8f, 0xce, 0xaa, 0x3b, 0xa5,
            0x68, 0xd3, 0x7f, 0xae, 0x31, 0x93, 0xe6, 0x69,
            0x0c, 0xd1, 0x74, 0x7f, 0x8f, 0xc2, 0xe2, 0x33,
            0x93, 0x45, 0x23, 0xba, 0xb3, 0x73, 0xc9, 0x2c,
            0xd6, 0xd2, 0x10, 0x16, 0xe9, 0x9f, 0x9e, 0xe8,
            0xc1, 0x0e, 0x29, 0x95, 0x3d, 0x16, 0x68, 0x24,
            0x40, 0x4d, 0x40, 0x21, 0x41, 0xa6, 0xc8, 0xdb },
      },
      {
          CKM_SP800_108_FEEDBACK_KDF,
          { CKM_SHA512_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          64,
          64,
          { 0x81, 0x39, 0x12, 0xc2, 0xf9, 0x31, 0x24, 0x7c,
            0x71, 0x12, 0x97, 0x08, 0x82, 0x76, 0x83, 0x55,
            0x8c, 0x82, 0xf3, 0x09, 0xd6, 0x1b, 0x7a, 0xa2,
            0x6e, 0x71, 0x6b, 0xad, 0x46, 0x57, 0x60, 0x89,
            0x38, 0xcf, 0x63, 0xfa, 0xf4, 0x38, 0x27, 0xef,
            0xf0, 0xaf, 0x75, 0x4e, 0xc2, 0xe0, 0x31, 0xdb,
            0x59, 0x7d, 0x19, 0xc9, 0x6d, 0xbb, 0xed, 0x95,
            0xaf, 0x3e, 0xd8, 0x33, 0x76, 0xab, 0xec, 0xfa },
      },
      {
          CKM_SP800_108_DOUBLE_PIPELINE_KDF,
          { CKM_AES_CMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          16,
          64,
          { 0x3e, 0xa8, 0xbf, 0x77, 0x84, 0x90, 0xb0, 0x3a,
            0x89, 0x16, 0x32, 0x01, 0x92, 0xd3, 0x1f, 0x1b,
            0xc1, 0x06, 0xc5, 0x32, 0x62, 0x03, 0x50, 0x16,
            0x3b, 0xb9, 0xa7, 0xdc, 0xb5, 0x68, 0x6a, 0xbb,
            0xbb, 0x7d, 0x63, 0x69, 0x24, 0x6e, 0x09, 0xd6,
            0x6f, 0x80, 0x57, 0x65, 0xc5, 0x62, 0x33, 0x96,
            0x69, 0xe6, 0xab, 0x65, 0x36, 0xd0, 0xe2, 0x5c,
            0xd7, 0xbd, 0xe4, 0x68, 0x13, 0xd6, 0xb1, 0x46 },
      },
      {
          CKM_SP800_108_DOUBLE_PIPELINE_KDF,
          { CKM_SHA256_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          32,
          64,
          { 0xeb, 0x28, 0xd9, 0x2c, 0x19, 0x33, 0xb9, 0x2a,
            0xf9, 0xac, 0x85, 0xbd, 0xf4, 0xdb, 0xfa, 0x88,
            0x73, 0xf4, 0x36, 0x08, 0xdb, 0xfe, 0x13, 0xd1,
            0x5a, 0xec, 0x7b, 0x68, 0x13, 0x53, 0xb3, 0xd1,
            0x31, 0xf2, 0x83, 0xae, 0x9f, 0x75, 0x47, 0xb6,
            0x6d, 0x3c, 0x20, 0x16, 0x47, 0x9c, 0x27, 0x66,
            0xec, 0xa9, 0xdf, 0x0c, 0xda, 0x2a, 0xf9, 0xf4,
            0x55, 0x74, 0xde, 0x9d, 0x3f, 0xe3, 0x5e, 0x14 },
      },
      {
          CKM_SP800_108_DOUBLE_PIPELINE_KDF,
          { CKM_SHA384_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          48,
          64,
          { 0xa5, 0xca, 0x32, 0x40, 0x00, 0x93, 0xb2, 0xcc,
            0x78, 0x3c, 0xa6, 0xc4, 0xaf, 0xa8, 0xb3, 0xd0,
            0xa4, 0x6b, 0xb5, 0x31, 0x35, 0x87, 0x33, 0xa2,
            0x6a, 0x6b, 0xe1, 0xff, 0xea, 0x1d, 0x6e, 0x9e,
            0x0b, 0xde, 0x8b, 0x92, 0x15, 0xd6, 0x56, 0x2f,
            0xb6, 0x1a, 0xd7, 0xd2, 0x01, 0x3e, 0x28, 0x2e,
            0xfa, 0x84, 0x3c, 0xc0, 0xe8, 0xbe, 0x94, 0xc0,
            0x06, 0xbd, 0xbf, 0x87, 0x1f, 0xb8, 0x64, 0xc2 },
      },
      {
          CKM_SP800_108_DOUBLE_PIPELINE_KDF,
          { CKM_SHA512_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
          64,
          64,
          { 0x3f, 0xd9, 0x4e, 0x80, 0x58, 0x21, 0xc8, 0xea,
            0x22, 0x17, 0xcf, 0x7d, 0xce, 0xfd, 0xec, 0x03,
            0xb9, 0xe4, 0xa2, 0xf7, 0xc0, 0xf1, 0x68, 0x81,
            0x53, 0x71, 0xb7, 0x42, 0x14, 0x4e, 0x5b, 0x09,
            0x05, 0x31, 0xb9, 0x27, 0x18, 0x2d, 0x23, 0xf8,
            0x9c, 0x3d, 0x4e, 0xd0, 0xdd, 0xf3, 0x1e, 0x4b,
            0xf2, 0xf9, 0x1a, 0x5d, 0x00, 0x66, 0x22, 0x83,
            0xae, 0x3c, 0x53, 0xd2, 0x54, 0x4b, 0x06, 0x4c },
      },
#endif
      {
          CKM_SP800_108_COUNTER_KDF,
          { CKM_SHA256_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_32_data, 0, NULL },
          32,
          64,
          { 0xfb, 0x2b, 0xb5, 0xde, 0xce, 0x5a, 0x2b, 0xdc,
            0x25, 0x8f, 0x54, 0x17, 0x4b, 0x5a, 0xa7, 0x90,
            0x64, 0x36, 0xeb, 0x43, 0x1f, 0x1d, 0xf9, 0x23,
            0xb2, 0x22, 0x29, 0xa0, 0xfa, 0x2e, 0x21, 0xb6,
            0xb7, 0xfb, 0x27, 0x0a, 0x1c, 0xa6, 0x58, 0x43,
            0xa1, 0x16, 0x44, 0x29, 0x4b, 0x1c, 0xb3, 0x72,
            0xd5, 0x98, 0x9d, 0x27, 0xd5, 0x75, 0x25, 0xbf,
            0x23, 0x61, 0x40, 0x48, 0xbb, 0x0b, 0x49, 0x8e },
      }
    };

SECStatus
sftk_fips_SP800_108_PowerUpSelfTests(void)
{
    int i;
    CK_RV crv;

    const unsigned char prf_key[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
        0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
        0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78
    };
    for (i = 0; i < PR_ARRAY_SIZE(sftk_SP800_Tests); i++) {
        const struct sftk_SP800_Test_struct *test = &sftk_SP800_Tests[i];
        unsigned char *output_buffer;
        size_t buffer_length;
        unsigned int mac_size;

        crv = kbkdf_RawDispatch(test->mech, &test->kdf_params,
                                prf_key, test->expected_mac_size,
                                NULL, prf_key, test->expected_mac_size,
                                &output_buffer, &buffer_length, &mac_size,
                                test->ret_key_length);
        if (crv != CKR_OK) {
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
        if ((mac_size != test->expected_mac_size) ||
            (buffer_length != test->ret_key_length) ||
            (output_buffer == NULL) ||
            (PORT_Memcmp(output_buffer, test->expected_key_bytes, buffer_length) != 0)) {
            PORT_ZFree(output_buffer, buffer_length);
            return SECFailure;
        }
        PORT_ZFree(output_buffer, buffer_length);
    }
    return SECSuccess;
}
