tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

kbkdf.c (61681B)


      1 #include "pkcs11i.h"
      2 #include "blapi.h"
      3 #include "secerr.h"
      4 #include "softoken.h"
      5 
      6 /* Overview:
      7 *
      8 * This file contains implementations of the three KDFs from NIST SP800-108
      9 * "Recommendation for Key Derivation Using Pseudorandom Functions":
     10 *
     11 *  1. KDF in Counter Mode (section 5.1)
     12 *  2. KDF in Feedback Mode (section 5.2)
     13 *  3. KDF in Double-Pipeline Iteration Mode (section 5.3)
     14 *
     15 * These KDFs are a form of negotiable building blocks for KDFs: protocol
     16 * designers can choose various fields, their endianness, and the underlying
     17 * PRF. These constructs are generic enough to handle creation of arbitrary,
     18 * (but known ahead of time) length outputs.
     19 *
     20 * The families of PRFs described here are used, among other places, in
     21 * Kerberos and GlobalPlatform's Secure Channel Protocol 03. The PKCS#11 v3.0
     22 * design for this KDF facilitates a wide range of uses.
     23 *
     24 * Implementation Details:
     25 *
     26 * We reuse the new sftk_MACCtx for handling the underlying MACing; with a few
     27 * safe restrictions, we can reuse whatever it gives us to use as a PRF.
     28 *
     29 * We implement the core of the KDF in the *Raw(...) version of the function
     30 * call. The PKCS#11 key handling happens in the non-Raw version. This means
     31 * we need a single large allocation upfront (large enough to store the entire
     32 * key stream), but means we can share key parsing logic and enable the
     33 * creation of data objects.
     34 */
     35 
     36 /* [ section: #define's ] */
     37 
     38 #define VALID_CK_BOOL(x) ((x) == CK_TRUE || (x) == CK_FALSE)
     39 #define IS_COUNTER(_mech) ((_mech) == CKM_SP800_108_COUNTER_KDF || (_mech) == CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA)
     40 #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)
     41 
     42 /* [ section: parameter validation ] */
     43 
     44 static CK_RV
     45 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)
     46 {
     47    /* This function loads the parameters for the given mechanism into the
     48     * specified kdf_params, splitting off the IV if present. In PKCS#11 v3.0,
     49     * CK_SP800_108_FEEDBACK_KDF_PARAMS and CK_SP800_108_KDF_PARAMS have
     50     * different ordering of internal parameters, which means that it isn't
     51     * easy to reuse feedback parameters in the same functions as non-feedback
     52     * parameters. Rather than duplicating the logic, split out the only
     53     * Feedback-specific data (the IV) into a separate argument and repack it
     54     * into the passed kdf_params struct instead. */
     55    PR_ASSERT(pMechanism != NULL && kdf_params != NULL && initial_value != NULL && initial_value_length != NULL);
     56 
     57    CK_SP800_108_KDF_PARAMS_PTR in_params;
     58    CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR feedback_params;
     59 
     60    if (mech == CKM_SP800_108_FEEDBACK_KDF || mech == CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA) {
     61        if (pMechanism->ulParameterLen != sizeof(CK_SP800_108_FEEDBACK_KDF_PARAMS)) {
     62            return CKR_MECHANISM_PARAM_INVALID;
     63        }
     64 
     65        feedback_params = (CK_SP800_108_FEEDBACK_KDF_PARAMS *)pMechanism->pParameter;
     66 
     67        if (feedback_params->pIV == NULL && feedback_params->ulIVLen > 0) {
     68            return CKR_MECHANISM_PARAM_INVALID;
     69        }
     70 
     71        kdf_params->prfType = feedback_params->prfType;
     72        kdf_params->ulNumberOfDataParams = feedback_params->ulNumberOfDataParams;
     73        kdf_params->pDataParams = feedback_params->pDataParams;
     74        kdf_params->ulAdditionalDerivedKeys = feedback_params->ulAdditionalDerivedKeys;
     75        kdf_params->pAdditionalDerivedKeys = feedback_params->pAdditionalDerivedKeys;
     76 
     77        *initial_value = feedback_params->pIV;
     78        *initial_value_length = feedback_params->ulIVLen;
     79    } else {
     80        if (pMechanism->ulParameterLen != sizeof(CK_SP800_108_KDF_PARAMS)) {
     81            return CKR_MECHANISM_PARAM_INVALID;
     82        }
     83 
     84        in_params = (CK_SP800_108_KDF_PARAMS *)pMechanism->pParameter;
     85 
     86        (*kdf_params) = *in_params;
     87    }
     88 
     89    return CKR_OK;
     90 }
     91 
     92 static CK_RV
     93 kbkdf_ValidateParameter(CK_MECHANISM_TYPE mech, const CK_PRF_DATA_PARAM *data)
     94 {
     95    /* This function validates that the passed data parameter (data) conforms
     96     * to PKCS#11 v3.0's expectations for KDF parameters. This depends both on
     97     * the type of this parameter (data->type) and on the KDF mechanism (mech)
     98     * as certain parameters are context dependent (like Iteration Variable).
     99     */
    100 
    101    /* If the parameter is missing a value when one is expected, then this
    102     * parameter is invalid. */
    103    if ((data->pValue == NULL) != (data->ulValueLen == 0)) {
    104        return CKR_MECHANISM_PARAM_INVALID;
    105    }
    106 
    107    switch (data->type) {
    108        case CK_SP800_108_ITERATION_VARIABLE:
    109        case CK_SP800_108_OPTIONAL_COUNTER: {
    110            if (data->type == CK_SP800_108_ITERATION_VARIABLE && !IS_COUNTER(mech)) {
    111                /* In Feedback and Double Pipeline KDFs, PKCS#11 v3.0 connotes the
    112                 * iteration variable as the chaining value from the previous PRF
    113                 * invocation. In contrast, counter mode treats this variable as a
    114                 * COUNTER_FORMAT descriptor. Thus we can skip validation of
    115                 * iteration variable parameters outside of counter mode. However,
    116                 * PKCS#11 v3.0 technically mandates that pValue is NULL, so we
    117                 * still have to validate that. */
    118 
    119                if (data->pValue != NULL) {
    120                    return CKR_MECHANISM_PARAM_INVALID;
    121                }
    122 
    123                return CKR_OK;
    124            }
    125 
    126            /* In counter mode, data->pValue should be a pointer to an instance of
    127             * CK_SP800_108_COUNTER_FORMAT; validate its length. */
    128            if (data->ulValueLen != sizeof(CK_SP800_108_COUNTER_FORMAT)) {
    129                return CKR_MECHANISM_PARAM_INVALID;
    130            }
    131 
    132            CK_SP800_108_COUNTER_FORMAT_PTR param = (CK_SP800_108_COUNTER_FORMAT_PTR)data->pValue;
    133 
    134            /* Validate the endian parameter. */
    135            if (!VALID_CK_BOOL(param->bLittleEndian)) {
    136                return CKR_MECHANISM_PARAM_INVALID;
    137            }
    138 
    139            /* Due to restrictions by our underlying hashes, we restrict bit
    140             * widths to actually be byte widths by ensuring they're a multiple
    141             * of eight. */
    142            if ((param->ulWidthInBits % 8) != 0) {
    143                return CKR_MECHANISM_PARAM_INVALID;
    144            }
    145 
    146            /* Note that section 5.1 denotes the maximum length of the counter
    147             * to be 32. */
    148            if (param->ulWidthInBits > 32) {
    149                return CKR_MECHANISM_PARAM_INVALID;
    150            }
    151            break;
    152        }
    153        case CK_SP800_108_DKM_LENGTH: {
    154            /* data->pValue should be a pointer to an instance of
    155             * CK_SP800_108_DKM_LENGTH_FORMAT; validate its length. */
    156            if (data->ulValueLen != sizeof(CK_SP800_108_DKM_LENGTH_FORMAT)) {
    157                return CKR_MECHANISM_PARAM_INVALID;
    158            }
    159 
    160            CK_SP800_108_DKM_LENGTH_FORMAT_PTR param = (CK_SP800_108_DKM_LENGTH_FORMAT_PTR)data->pValue;
    161 
    162            /* Validate the method parameter. */
    163            if (param->dkmLengthMethod != CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS &&
    164                param->dkmLengthMethod != CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS) {
    165                return CKR_MECHANISM_PARAM_INVALID;
    166            }
    167 
    168            /* Validate the endian parameter. */
    169            if (!VALID_CK_BOOL(param->bLittleEndian)) {
    170                return CKR_MECHANISM_PARAM_INVALID;
    171            }
    172 
    173            /* Validate the maximum width: we restrict it to being a byte width
    174             * instead of a bit width due to restrictions by the underlying
    175             * PRFs. */
    176            if ((param->ulWidthInBits % 8) != 0) {
    177                return CKR_MECHANISM_PARAM_INVALID;
    178            }
    179 
    180            /* Ensure that the width doesn't overflow a 64-bit int. This
    181             * restriction is arbitrary but since the counters can't exceed
    182             * 32-bits (and most PRFs output at most 1024 bits), you're unlikely
    183             * to need all 64-bits of length indicator. */
    184            if (param->ulWidthInBits > 64) {
    185                return CKR_MECHANISM_PARAM_INVALID;
    186            }
    187            break;
    188        }
    189        case CK_SP800_108_BYTE_ARRAY:
    190            /* There is no additional data to validate for byte arrays; we can
    191             * only assume the byte array is of the specified size. */
    192            break;
    193        default:
    194            /* Unexpected parameter type. */
    195            return CKR_MECHANISM_PARAM_INVALID;
    196    }
    197 
    198    return CKR_OK;
    199 }
    200 
    201 static CK_RV
    202 kbkdf_ValidateDerived(CK_DERIVED_KEY_PTR key)
    203 {
    204    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    205    PRUint64 keySize = 0;
    206 
    207    /* The pointer to the key handle shouldn't be NULL. If it is, we can't
    208     * do anything else, so exit early. Every other failure case sets the
    209     * key->phKey = CK_INVALID_HANDLE, so we can't use `goto failure` here. */
    210    if (key->phKey == NULL) {
    211        return CKR_MECHANISM_PARAM_INVALID;
    212    }
    213 
    214    /* Validate that we have no attributes if and only if pTemplate is NULL.
    215     * Otherwise, there's an inconsistency somewhere. */
    216    if ((key->ulAttributeCount == 0) != (key->pTemplate == NULL)) {
    217        goto failure;
    218    }
    219 
    220    for (size_t offset = 0; offset < key->ulAttributeCount; offset++) {
    221        CK_ATTRIBUTE_PTR template = key->pTemplate + offset;
    222 
    223        /* We only look for the CKA_VALUE_LEN and CKA_KEY_TYPE attributes.
    224         * Everything else we assume we can set on the key if it is passed
    225         * here. However, if we can't inquire as to a length (and barring
    226         * that, if we have a key type without a standard length), we're
    227         * definitely stuck. This mirrors the logic at the top of
    228         * NSC_DeriveKey(...). */
    229        if (template->type == CKA_KEY_TYPE) {
    230            if (template->ulValueLen != sizeof(CK_KEY_TYPE)) {
    231                goto failure;
    232            }
    233 
    234            keyType = *(CK_KEY_TYPE *)template->pValue;
    235        } else if (template->type == CKA_VALUE_LEN) {
    236            if (template->ulValueLen != sizeof(CK_ULONG)) {
    237                goto failure;
    238            }
    239 
    240            keySize = *(CK_ULONG *)template->pValue;
    241        }
    242    }
    243 
    244    if (keySize == 0) {
    245        /* When we lack a keySize, see if we can infer it from the type of the
    246         * passed key. */
    247        keySize = sftk_MapKeySize(keyType);
    248    }
    249 
    250    /* The main piece of information we validate is that we have a length for
    251     * this key. */
    252    if (keySize == 0 || keySize >= (1ull << 32ull)) {
    253        goto failure;
    254    }
    255 
    256    return CKR_OK;
    257 
    258 failure:
    259    /* PKCS#11 v3.0: If the failure was caused by the content of a specific
    260     * key's template (ie the template defined by the content of pTemplate),
    261     * the corresponding phKey value will be set to CK_INVALID_HANDLE to
    262     * identify the offending template. */
    263    *(key->phKey) = CK_INVALID_HANDLE;
    264    return CKR_MECHANISM_PARAM_INVALID;
    265 }
    266 
    267 static PRBool
    268 kbkdf_ValidPRF(CK_SP800_108_PRF_TYPE prf)
    269 {
    270    // See Table 161 of PKCS#11 v3.0 or Table 192 of PKCS#11 v3.1.
    271    switch (prf) {
    272        case CKM_AES_CMAC:
    273            /* case CKM_DES3_CMAC: */
    274            return PR_TRUE;
    275        case CKM_SHA_1_HMAC:
    276        case CKM_SHA224_HMAC:
    277        case CKM_SHA256_HMAC:
    278        case CKM_SHA384_HMAC:
    279        case CKM_SHA512_HMAC:
    280        case CKM_SHA3_224_HMAC:
    281        case CKM_SHA3_256_HMAC:
    282        case CKM_SHA3_384_HMAC:
    283        case CKM_SHA3_512_HMAC:
    284            /* Valid HMAC <-> HASH isn't NULL */
    285            return sftk_HMACMechanismToHash(prf) != HASH_AlgNULL;
    286    }
    287    return PR_FALSE;
    288 }
    289 
    290 static CK_RV
    291 kbkdf_ValidateParameters(CK_MECHANISM_TYPE mech, const CK_SP800_108_KDF_PARAMS *params, CK_ULONG keySize)
    292 {
    293    CK_RV ret = CKR_MECHANISM_PARAM_INVALID;
    294    int param_type_count[5] = { 0, 0, 0, 0, 0 };
    295    size_t offset = 0;
    296 
    297    /* Start with checking the prfType as a mechanism against a list of
    298     * PRFs allowed by PKCS#11 v3.0. */
    299    if (!kbkdf_ValidPRF(params->prfType)) {
    300        return CKR_MECHANISM_PARAM_INVALID;
    301    }
    302 
    303    /* We can't have a null pDataParams pointer: we always need at least one
    304     * parameter to succeed. */
    305    if (params->pDataParams == NULL) {
    306        return CKR_HOST_MEMORY;
    307    }
    308 
    309    /* Validate each KDF parameter. */
    310    for (offset = 0; offset < params->ulNumberOfDataParams; offset++) {
    311        /* Validate this parameter has acceptable values. */
    312        ret = kbkdf_ValidateParameter(mech, params->pDataParams + offset);
    313        if (ret != CKR_OK) {
    314            return CKR_MECHANISM_PARAM_INVALID;
    315        }
    316 
    317        /* Count that we have a parameter of this type. The above logic
    318         * in ValidateParameter MUST validate that type is within the
    319         * appropriate range. */
    320        PR_ASSERT(params->pDataParams[offset].type < sizeof(param_type_count) / sizeof(param_type_count[0]));
    321        param_type_count[params->pDataParams[offset].type] += 1;
    322    }
    323 
    324    if (IS_COUNTER(mech)) {
    325        /* We have to have at least one iteration variable parameter. */
    326        if (param_type_count[CK_SP800_108_ITERATION_VARIABLE] == 0) {
    327            return CKR_MECHANISM_PARAM_INVALID;
    328        }
    329 
    330        /* We can't have any optional counters parameters -- these belong in
    331         * iteration variable parameters instead. */
    332        if (param_type_count[CK_SP800_108_OPTIONAL_COUNTER] != 0) {
    333            return CKR_MECHANISM_PARAM_INVALID;
    334        }
    335    }
    336 
    337    /* Validate basic assumptions about derived keys:
    338     *      NULL <-> ulAdditionalDerivedKeys > 0
    339     */
    340    if ((params->ulAdditionalDerivedKeys == 0) != (params->pAdditionalDerivedKeys == NULL)) {
    341        return CKR_MECHANISM_PARAM_INVALID;
    342    }
    343 
    344    /* Validate each derived key. */
    345    for (offset = 0; offset < params->ulAdditionalDerivedKeys; offset++) {
    346        ret = kbkdf_ValidateDerived(params->pAdditionalDerivedKeys + offset);
    347        if (ret != CKR_OK) {
    348            return CKR_MECHANISM_PARAM_INVALID;
    349        }
    350    }
    351 
    352    /* Validate the length of our primary key. */
    353    if (keySize == 0 || ((PRUint64)keySize) >= (1ull << 32ull)) {
    354        return CKR_KEY_SIZE_RANGE;
    355    }
    356 
    357    return CKR_OK;
    358 }
    359 
    360 /* [ section: parameter helpers ] */
    361 
    362 static CK_VOID_PTR
    363 kbkdf_FindParameter(const CK_SP800_108_KDF_PARAMS *params, CK_PRF_DATA_TYPE type)
    364 {
    365    for (size_t offset = 0; offset < params->ulNumberOfDataParams; offset++) {
    366        if (params->pDataParams[offset].type == type) {
    367            return params->pDataParams[offset].pValue;
    368        }
    369    }
    370 
    371    return NULL;
    372 }
    373 
    374 size_t
    375 kbkdf_IncrementBuffer(size_t cur_offset, size_t consumed, size_t prf_length)
    376 {
    377    return cur_offset + PR_ROUNDUP(consumed, prf_length);
    378 }
    379 
    380 CK_ULONG
    381 kbkdf_GetDerivedKeySize(CK_DERIVED_KEY_PTR derived_key)
    382 {
    383    /* Precondition: kbkdf_ValidateDerived(...) returns CKR_OK for this key,
    384     * which implies that keySize is defined. */
    385 
    386    CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
    387    CK_ULONG keySize = 0;
    388 
    389    for (size_t offset = 0; offset < derived_key->ulAttributeCount; offset++) {
    390        CK_ATTRIBUTE_PTR template = derived_key->pTemplate + offset;
    391 
    392        /* Find the two attributes we care about. */
    393        if (template->type == CKA_KEY_TYPE) {
    394            keyType = *(CK_KEY_TYPE *)template->pValue;
    395        } else if (template->type == CKA_VALUE_LEN) {
    396            keySize = *(CK_ULONG *)template->pValue;
    397        }
    398    }
    399 
    400    /* Prefer keySize, if we have it. */
    401    if (keySize > 0) {
    402        return keySize;
    403    }
    404 
    405    /* Else, fall back to this mapping. We know kbkdf_ValidateDerived(...)
    406     * passed, so this should return non-zero. */
    407    return sftk_MapKeySize(keyType);
    408 }
    409 
    410 static CK_RV
    411 kbkdf_CalculateLength(const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, CK_ULONG ret_key_size, PRUint64 *output_bitlen, size_t *buffer_length)
    412 {
    413    /* Two cases: either we have additional derived keys or we don't. In the
    414     * case that we don't, the length of the derivation is the size of the
    415     * single derived key, and that is the length of the PRF buffer. Otherwise,
    416     * we need to use the proper CK_SP800_108_DKM_LENGTH_METHOD to calculate
    417     * the length of the output (in bits), with a separate value for the size
    418     * of the PRF data buffer. This means that, under PKCS#11 with additional
    419     * derived keys, we lie to the KDF about the _actual_ length of the PRF
    420     * output.
    421     *
    422     * Note that *output_bitlen is the L parameter in NIST SP800-108 and is in
    423     * bits. However, *buffer_length is in bytes.
    424     */
    425 
    426    if (params->ulAdditionalDerivedKeys == 0) {
    427        /* When we have no additional derived keys, we get the keySize from
    428         * the value passed to one of our KBKDF_* methods. */
    429        *output_bitlen = ret_key_size;
    430        *buffer_length = ret_key_size;
    431    } else {
    432        /* Offset in the additional derived keys array. */
    433        size_t offset = 0;
    434 
    435        /* Size of the derived key. */
    436        CK_ULONG derived_size = 0;
    437 
    438        /* In the below, we place the sum of the keys into *output_bitlen
    439         * and the size of the buffer (with padding mandated by PKCS#11 v3.0)
    440         * into *buffer_length. If the method is the segment sum, then we
    441         * replace *output_bitlen with *buffer_length at the end. This ensures
    442         * we always get a output buffer large enough to handle all derived
    443         * keys, and *output_bitlen reflects the correct L value. */
    444 
    445        /* Count the initial derived key. */
    446        *output_bitlen = ret_key_size;
    447        *buffer_length = kbkdf_IncrementBuffer(0, ret_key_size, ctx->mac_size);
    448 
    449        /* Handle n - 1 keys. The last key is special. */
    450        for (; offset < params->ulAdditionalDerivedKeys - 1; offset++) {
    451            derived_size = kbkdf_GetDerivedKeySize(params->pAdditionalDerivedKeys + offset);
    452 
    453            *output_bitlen += derived_size;
    454            *buffer_length = kbkdf_IncrementBuffer(*buffer_length, derived_size, ctx->mac_size);
    455        }
    456 
    457        /* Handle the last key. */
    458        derived_size = kbkdf_GetDerivedKeySize(params->pAdditionalDerivedKeys + offset);
    459 
    460        *output_bitlen += derived_size;
    461        *buffer_length = kbkdf_IncrementBuffer(*buffer_length, derived_size, ctx->mac_size);
    462 
    463        /* Pointer to the DKM method parameter. Note that this implicit cast
    464         * is safe since we've assumed we've been validated by
    465         * kbkdf_ValidateParameters(...). When kdm_param is NULL, we don't
    466         * use the output_bitlen parameter. */
    467        CK_SP800_108_DKM_LENGTH_FORMAT_PTR dkm_param = kbkdf_FindParameter(params, CK_SP800_108_DKM_LENGTH);
    468        if (dkm_param != NULL) {
    469            if (dkm_param->dkmLengthMethod == CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS) {
    470                *output_bitlen = *buffer_length;
    471            }
    472        }
    473    }
    474 
    475    /* Note that keySize is the size in bytes and ctx->mac_size is also
    476     * the size in bytes. However, output_bitlen needs to be in bits, so
    477     * multiply by 8 here. */
    478    *output_bitlen *= 8;
    479 
    480    return CKR_OK;
    481 }
    482 
    483 static CK_RV
    484 kbkdf_CalculateIterations(CK_MECHANISM_TYPE mech, const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, size_t buffer_length, PRUint32 *num_iterations)
    485 {
    486    CK_SP800_108_COUNTER_FORMAT_PTR param_ptr = NULL;
    487    PRUint64 iteration_count;
    488    PRUint64 r = 32;
    489 
    490    /* We need to know how many full iterations are required. This is done
    491     * by rounding up the division of the PRF length into buffer_length.
    492     * However, we're not guaranteed that the last output is a full PRF
    493     * invocation, so handle that here. */
    494    iteration_count = buffer_length + (ctx->mac_size - 1);
    495    iteration_count = iteration_count / ctx->mac_size;
    496 
    497    /* NIST SP800-108, section 5.1, process step #2:
    498     *
    499     *      if n > 2^r - 1, then indicate an error and stop.
    500     *
    501     * In non-counter mode KDFs, r is set at 32, leaving behavior
    502     * under-defined when the optional counter is included but fewer than
    503     * 32 bits. This implementation assumes r is 32, but if the counter
    504     * parameter is included, validates it against that. In counter-mode
    505     * KDFs, this is in the ITERATION_VARIABLE parameter; in feedback- or
    506     * pipeline-mode KDFs, this is in the COUNTER parameter.
    507     *
    508     * This is consistent with the supplied sample CAVP tests; none reuses the
    509     * same counter value. In some configurations, this could result in
    510     * duplicated KDF output. We seek to avoid that from happening.
    511     */
    512    if (IS_COUNTER(mech)) {
    513        param_ptr = kbkdf_FindParameter(params, CK_SP800_108_ITERATION_VARIABLE);
    514 
    515        /* Validated by kbkdf_ValidateParameters(...) above. */
    516        PR_ASSERT(param_ptr != NULL);
    517 
    518        r = ((CK_SP800_108_COUNTER_FORMAT_PTR)param_ptr)->ulWidthInBits;
    519    } else {
    520        param_ptr = kbkdf_FindParameter(params, CK_SP800_108_COUNTER);
    521 
    522        /* Not guaranteed to exist, hence the default value of r=32. */
    523        if (param_ptr != NULL) {
    524            r = ((CK_SP800_108_COUNTER_FORMAT_PTR)param_ptr)->ulWidthInBits;
    525        }
    526    }
    527 
    528    if (iteration_count >= (1ull << r) || r > 32) {
    529        return CKR_MECHANISM_PARAM_INVALID;
    530    }
    531 
    532    *num_iterations = (PRUint32)iteration_count;
    533 
    534    return CKR_OK;
    535 }
    536 
    537 static CK_RV
    538 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)
    539 {
    540    size_t offset = 0;
    541    CK_RV ret = CKR_OK;
    542 
    543    for (offset = 0; offset < params->ulNumberOfDataParams; offset++) {
    544        CK_PRF_DATA_PARAM_PTR param = params->pDataParams + offset;
    545 
    546        if (param->type == exclude) {
    547            /* Necessary for Double Pipeline mode: when constructing the IV,
    548             * we skip the  optional counter. */
    549            continue;
    550        }
    551 
    552        switch (param->type) {
    553            case CK_SP800_108_ITERATION_VARIABLE: {
    554                /* When present in COUNTER mode, this signifies adding the counter
    555                 * variable to the PRF. Otherwise, it signifies the chaining
    556                 * value for other KDF modes. */
    557                if (IS_COUNTER(mech)) {
    558                    CK_SP800_108_COUNTER_FORMAT_PTR counter_format = (CK_SP800_108_COUNTER_FORMAT_PTR)param->pValue;
    559                    CK_BYTE buffer[sizeof(PRUint64)];
    560                    CK_ULONG num_bytes;
    561                    sftk_EncodeInteger(counter, counter_format->ulWidthInBits, counter_format->bLittleEndian, buffer, &num_bytes);
    562                    ret = sftk_MAC_Update(ctx, buffer, num_bytes);
    563                } else {
    564                    ret = sftk_MAC_Update(ctx, chaining_prf, chaining_prf_len);
    565                }
    566                break;
    567            }
    568            case CK_SP800_108_COUNTER: {
    569                /* Only present in the case when not using COUNTER mode. */
    570                PR_ASSERT(!IS_COUNTER(mech));
    571 
    572                /* We should've already validated that this parameter is of
    573                 * type COUNTER_FORMAT. */
    574                CK_SP800_108_COUNTER_FORMAT_PTR counter_format = (CK_SP800_108_COUNTER_FORMAT_PTR)param->pValue;
    575                CK_BYTE buffer[sizeof(PRUint64)];
    576                CK_ULONG num_bytes;
    577                sftk_EncodeInteger(counter, counter_format->ulWidthInBits, counter_format->bLittleEndian, buffer, &num_bytes);
    578                ret = sftk_MAC_Update(ctx, buffer, num_bytes);
    579                break;
    580            }
    581            case CK_SP800_108_BYTE_ARRAY:
    582                ret = sftk_MAC_Update(ctx, (CK_BYTE_PTR)param->pValue, param->ulValueLen);
    583                break;
    584            case CK_SP800_108_DKM_LENGTH: {
    585                /* We've already done the hard work of calculating the length in
    586                 * the kbkdf_CalculateIterations function; we merely need to add
    587                 * the length to the desired point in the input stream. */
    588                CK_SP800_108_DKM_LENGTH_FORMAT_PTR length_format = (CK_SP800_108_DKM_LENGTH_FORMAT_PTR)param->pValue;
    589                CK_BYTE buffer[sizeof(PRUint64)];
    590                CK_ULONG num_bytes;
    591                sftk_EncodeInteger(length, length_format->ulWidthInBits, length_format->bLittleEndian, buffer, &num_bytes);
    592                ret = sftk_MAC_Update(ctx, buffer, num_bytes);
    593                break;
    594            }
    595            default:
    596                /* This should've been caught by kbkdf_ValidateParameters(...). */
    597                PR_ASSERT(PR_FALSE);
    598                return CKR_MECHANISM_PARAM_INVALID;
    599        }
    600 
    601        if (ret != CKR_OK) {
    602            return ret;
    603        }
    604    }
    605 
    606    return CKR_OK;
    607 }
    608 
    609 CK_RV
    610 kbkdf_SaveKey(SFTKObject *key, unsigned char *key_buffer, unsigned int key_len)
    611 {
    612    return sftk_forceAttribute(key, CKA_VALUE, key_buffer, key_len);
    613 }
    614 
    615 CK_RV
    616 kbkdf_CreateKey(CK_MECHANISM_TYPE kdf_mech, CK_SESSION_HANDLE hSession, CK_DERIVED_KEY_PTR derived_key, SFTKObject **ret_key)
    617 {
    618    /* Largely duplicated from NSC_DeriveKey(...) */
    619    CK_RV ret = CKR_HOST_MEMORY;
    620    SFTKObject *key = NULL;
    621    SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
    622    size_t offset = 0;
    623 
    624    /* Slot should be non-NULL because NSC_DeriveKey(...) has already
    625     * performed a sftk_SlotFromSessionHandle(...) call on this session
    626     * handle. However, Coverity incorrectly flagged this (see 1607955). */
    627    PR_ASSERT(slot != NULL);
    628    PR_ASSERT(ret_key != NULL);
    629    PR_ASSERT(derived_key != NULL);
    630    PR_ASSERT(derived_key->phKey != NULL);
    631 
    632    if (slot == NULL) {
    633        return CKR_SESSION_HANDLE_INVALID;
    634    }
    635 
    636    /* Create the new key object for this additional derived key. */
    637    key = sftk_NewObject(slot);
    638    if (key == NULL) {
    639        return CKR_HOST_MEMORY;
    640    }
    641 
    642    /* Setup the key from the provided template. */
    643    for (offset = 0; offset < derived_key->ulAttributeCount; offset++) {
    644        ret = sftk_AddAttributeType(key, sftk_attr_expand(derived_key->pTemplate + offset));
    645        if (ret != CKR_OK) {
    646            sftk_FreeObject(key);
    647            return ret;
    648        }
    649    }
    650 
    651    /* When using the CKM_SP800_* series of mechanisms, the result must be a
    652     * secret key, so its contents can be adequately protected in FIPS mode.
    653     * However, when using the special CKM_NSS_SP800_*_DERIVE_DATA series, the
    654     * contents need not be protected, so we set CKO_DATA on these "keys". */
    655    CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
    656    if (DOES_DERIVE_DATA(kdf_mech)) {
    657        classType = CKO_DATA;
    658    }
    659 
    660    ret = sftk_forceAttribute(key, CKA_CLASS, &classType, sizeof(classType));
    661    if (ret != CKR_OK) {
    662        sftk_FreeObject(key);
    663        return ret;
    664    }
    665 
    666    *ret_key = key;
    667    return CKR_OK;
    668 }
    669 
    670 CK_RV
    671 kbkdf_FinalizeKey(CK_SESSION_HANDLE hSession, CK_DERIVED_KEY_PTR derived_key, SFTKObject *key)
    672 {
    673    /* Largely duplicated from NSC_DeriveKey(...) */
    674    CK_RV ret = CKR_HOST_MEMORY;
    675    SFTKSession *session = NULL;
    676 
    677    PR_ASSERT(derived_key != NULL && key != NULL);
    678 
    679    SFTKSessionObject *sessionForKey = sftk_narrowToSessionObject(key);
    680    PR_ASSERT(sessionForKey != NULL);
    681    sessionForKey->wasDerived = PR_TRUE;
    682 
    683    session = sftk_SessionFromHandle(hSession);
    684 
    685    /* Session should be non-NULL because NSC_DeriveKey(...) has already
    686     * performed a sftk_SessionFromHandle(...) call on this session handle. */
    687    PR_ASSERT(session != NULL);
    688 
    689    ret = sftk_handleObject(key, session);
    690    if (ret != CKR_OK) {
    691        goto done;
    692    }
    693 
    694    *(derived_key->phKey) = key->handle;
    695 
    696 done:
    697    /* Guaranteed that key != NULL */
    698    sftk_FreeObject(key);
    699 
    700    /* Doesn't do anything. */
    701    if (session) {
    702        sftk_FreeSession(session);
    703    }
    704 
    705    return ret;
    706 }
    707 
    708 CK_RV
    709 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)
    710 {
    711    CK_RV ret;
    712    size_t key_offset = 0;
    713    size_t buffer_offset = 0;
    714 
    715    PR_ASSERT(output_buffer != NULL && buffer_len > 0 && ret_key != NULL);
    716 
    717    /* First place key material into the main key. */
    718    ret = kbkdf_SaveKey(ret_key, output_buffer + buffer_offset, ret_key_size);
    719    if (ret != CKR_OK) {
    720        return ret;
    721    }
    722 
    723    /* Then increment the offset based on PKCS#11 additional key guidelines:
    724     * no two keys may share the key stream from the same PRF invocation. */
    725    buffer_offset = kbkdf_IncrementBuffer(buffer_offset, ret_key_size, prf_length);
    726 
    727    if (params->ulAdditionalDerivedKeys > 0) {
    728        /* Note that the following code is technically incorrect: PKCS#11 v3.0
    729         * says that _no_ key should be set in the event of failure to derive
    730         * _any_ key. */
    731        for (key_offset = 0; key_offset < params->ulAdditionalDerivedKeys; key_offset++) {
    732            CK_DERIVED_KEY_PTR derived_key = params->pAdditionalDerivedKeys + key_offset;
    733            SFTKObject *key_obj = NULL;
    734            size_t key_size = kbkdf_GetDerivedKeySize(derived_key);
    735 
    736            /* Create a new internal key object for this derived key. */
    737            ret = kbkdf_CreateKey(mech, hSession, derived_key, &key_obj);
    738            if (ret != CKR_OK) {
    739                *(derived_key->phKey) = CK_INVALID_HANDLE;
    740                return ret;
    741            }
    742 
    743            /* Save the underlying key bytes to the key object. */
    744            ret = kbkdf_SaveKey(key_obj, output_buffer + buffer_offset, key_size);
    745            if (ret != CKR_OK) {
    746                /* When kbkdf_CreateKey(...) exits with an error, it will free
    747                 * the constructed key object. kbkdf_FinalizeKey(...) also
    748                 * always frees the key object. In the unlikely event that
    749                 * kbkdf_SaveKey(...) _does_ fail, we thus need to free it
    750                 * manually. */
    751                sftk_FreeObject(key_obj);
    752                *(derived_key->phKey) = CK_INVALID_HANDLE;
    753                return ret;
    754            }
    755 
    756            /* Handle the increment. */
    757            buffer_offset = kbkdf_IncrementBuffer(buffer_offset, key_size, prf_length);
    758 
    759            /* Finalize this key. */
    760            ret = kbkdf_FinalizeKey(hSession, derived_key, key_obj);
    761            if (ret != CKR_OK) {
    762                *(derived_key->phKey) = CK_INVALID_HANDLE;
    763                return ret;
    764            }
    765        }
    766    }
    767 
    768    return CKR_OK;
    769 }
    770 
    771 /* [ section: KDFs ] */
    772 
    773 static CK_RV
    774 kbkdf_CounterRaw(const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, unsigned char *ret_buffer, size_t buffer_length, PRUint64 output_bitlen)
    775 {
    776    CK_RV ret = CKR_OK;
    777 
    778    /* Counter variable for this KDF instance. */
    779    PRUint32 counter;
    780 
    781    /* Number of iterations required of this PRF necessary to reach the
    782     * desired output length. */
    783    PRUint32 num_iterations;
    784 
    785    /* Offset in ret_buffer that we're at. */
    786    size_t buffer_offset = 0;
    787 
    788    /* Size of this block, in bytes. Defaults to ctx->mac_size except on
    789     * the last iteration where it could be a partial block. */
    790    size_t block_size = ctx->mac_size;
    791 
    792    /* Calculate the number of iterations required based on the size of the
    793     * output buffer. */
    794    ret = kbkdf_CalculateIterations(CKM_SP800_108_COUNTER_KDF, params, ctx, buffer_length, &num_iterations);
    795    if (ret != CKR_OK) {
    796        return ret;
    797    }
    798 
    799    /*
    800     * 5.1 - [ KDF in Counter Mode ]
    801     *
    802     * Fixed values:
    803     *      1. h - the length of the PRF in bits (ctx->mac_size)
    804     *      2. r - the length of the binary representation of the counter i
    805     *          (params[k: params[k].type == CK_SP800_108_ITERATION_VARIABLE:].data->ulWidthInBits)
    806     * Input:
    807     *      1. K_I - the key for the PRF (base_key)
    808     *      2. label - a binary data field, usually before the separator. Optional.
    809     *      3. context - a binary data field, usually after the separator. Optional.
    810     *      4. L - length of the output in bits (output_bitlen)
    811     *
    812     * Process:
    813     *      1. n := ceil(L / h) (num_iterations)
    814     *      2. if n > 2^r - 1, then indicate an error and stop
    815     *      3. result(0) = NULL
    816     *      4. for i = 1 to n, do
    817     *          a. K(i) = PRF(K_I, [i]_2 || Label || 0x00 || Context || [L]_2)
    818     *          b. result(i) := result(i - 1) || K(i).
    819     *      5. return K_O := the leftmost L bits of result(n).
    820     */
    821    for (counter = 1; counter <= num_iterations; counter++) {
    822        if (counter == num_iterations) {
    823            block_size = buffer_length - buffer_offset;
    824 
    825            /* Assumption: if we've validated our arguments correctly, this
    826             * should always be true. */
    827            PR_ASSERT(block_size <= ctx->mac_size);
    828        }
    829 
    830        /* Add all parameters required by this instance of the KDF to the
    831         * input stream of the underlying PRF. */
    832        ret = kbkdf_AddParameters(CKM_SP800_108_COUNTER_KDF, ctx, params, counter, output_bitlen, NULL, 0 /* chaining_prf output */, 0 /* exclude */);
    833        if (ret != CKR_OK) {
    834            return ret;
    835        }
    836 
    837        /* Finalize this iteration of the PRF. */
    838        ret = sftk_MAC_End(ctx, ret_buffer + buffer_offset, NULL, block_size);
    839        if (ret != CKR_OK) {
    840            return ret;
    841        }
    842 
    843        /* Increment our position in the key material. */
    844        buffer_offset += block_size;
    845 
    846        if (counter < num_iterations) {
    847            /* Reset the underlying PRF for the next iteration. Only do this
    848             * when we have a next iteration since it isn't necessary to do
    849             * either before the first iteration (MAC is already initialized)
    850             * or after the last iteration (we won't be called again). */
    851            ret = sftk_MAC_Reset(ctx);
    852            if (ret != CKR_OK) {
    853                return ret;
    854            }
    855        }
    856    }
    857 
    858    return CKR_OK;
    859 }
    860 
    861 static CK_RV
    862 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)
    863 {
    864    CK_RV ret = CKR_OK;
    865 
    866    /* Counter variable for this KDF instance. */
    867    PRUint32 counter;
    868 
    869    /* Number of iterations required of this PRF necessary to reach the
    870     * desired output length. */
    871    PRUint32 num_iterations;
    872 
    873    /* Offset in ret_buffer that we're at. */
    874    size_t buffer_offset = 0;
    875 
    876    /* Size of this block, in bytes. Defaults to ctx->mac_size except on
    877     * the last iteration where it could be a partial block. */
    878    size_t block_size = ctx->mac_size;
    879 
    880    /* The last PRF invocation and/or the initial value; used for feedback
    881     * chaining in this KDF. Note that we have to make it large enough to
    882     * fit the output of the PRF, but we can delay its actual creation until
    883     * the first PRF invocation. Until then, point to the IV value. */
    884    unsigned char *chaining_value = (unsigned char *)initial_value;
    885 
    886    /* Size of the chaining value discussed above. Defaults to the size of
    887     * the IV value. */
    888    size_t chaining_length = initial_value_length;
    889 
    890    /* Calculate the number of iterations required based on the size of the
    891     * output buffer. */
    892    ret = kbkdf_CalculateIterations(CKM_SP800_108_FEEDBACK_KDF, params, ctx, buffer_length, &num_iterations);
    893    if (ret != CKR_OK) {
    894        goto finish;
    895    }
    896 
    897    /*
    898     * 5.2 - [ KDF in Feedback Mode ]
    899     *
    900     * Fixed values:
    901     *      1. h - the length of the PRF in bits (ctx->mac_size)
    902     *      2. r - the length of the binary representation of the counter i
    903     *          (params[k: params[k].type == CK_SP800_108_OPTIONAL_COUNTER:].data->ulWidthInBits)
    904     *          Note that it is only specified when the optional counter is requested.
    905     * Input:
    906     *      1. K_I - the key for the PRF (base_key)
    907     *      2. label - a binary data field, usually before the separator. Optional.
    908     *      3. context - a binary data field, usually after the separator. Optional.
    909     *      4. IV - a binary data field, initial PRF value. (params->pIV)
    910     *      5. L - length of the output in bits (output_bitlen)
    911     *
    912     * Process:
    913     *      1. n := ceil(L / h) (num_iterations)
    914     *      2. if n > 2^32 - 1, then indicate an error and stop
    915     *      3. result(0) = NULL, K(0) := IV (chaining_value)
    916     *      4. for i = 1 to n, do
    917     *          a. K(i) = PRF(K_I, K(i-1) {|| [i]_2} || Label || 0x00 || Context || [L]_2)
    918     *          b. result(i) := result(i - 1) || K(i).
    919     *      5. return K_O := the leftmost L bits of result(n).
    920     */
    921    for (counter = 1; counter <= num_iterations; counter++) {
    922        if (counter == num_iterations) {
    923            block_size = buffer_length - buffer_offset;
    924 
    925            /* Assumption: if we've validated our arguments correctly, this
    926             * should always be true. */
    927            PR_ASSERT(block_size <= ctx->mac_size);
    928        }
    929 
    930        /* Add all parameters required by this instance of the KDF to the
    931         * input stream of the underlying PRF. */
    932        ret = kbkdf_AddParameters(CKM_SP800_108_FEEDBACK_KDF, ctx, params, counter, output_bitlen, chaining_value, chaining_length, 0 /* exclude */);
    933        if (ret != CKR_OK) {
    934            goto finish;
    935        }
    936 
    937        if (counter == 1) {
    938            /* On the first iteration, chaining_value points to the IV from
    939             * the caller and chaining_length is the length of that IV. We
    940             * now need to allocate a buffer of suitable length to store the
    941             * MAC output. */
    942            chaining_value = PORT_ZNewArray(unsigned char, ctx->mac_size);
    943            chaining_length = ctx->mac_size;
    944 
    945            if (chaining_value == NULL) {
    946                ret = CKR_HOST_MEMORY;
    947                goto finish;
    948            }
    949        }
    950 
    951        /* Finalize this iteration of the PRF. Unlike other KDF forms, we
    952         * first save this to the chaining value so that we can reuse it
    953         * in the next iteration before copying the necessary length to
    954         * the output buffer. */
    955        ret = sftk_MAC_End(ctx, chaining_value, NULL, chaining_length);
    956        if (ret != CKR_OK) {
    957            goto finish;
    958        }
    959 
    960        /* Save as much of the chaining value as we need for output. */
    961        PORT_Memcpy(ret_buffer + buffer_offset, chaining_value, block_size);
    962 
    963        /* Increment our position in the key material. */
    964        buffer_offset += block_size;
    965 
    966        if (counter < num_iterations) {
    967            /* Reset the underlying PRF for the next iteration. Only do this
    968             * when we have a next iteration since it isn't necessary to do
    969             * either before the first iteration (MAC is already initialized)
    970             * or after the last iteration (we won't be called again). */
    971            ret = sftk_MAC_Reset(ctx);
    972            if (ret != CKR_OK) {
    973                goto finish;
    974            }
    975        }
    976    }
    977 
    978 finish:
    979    if (chaining_value != initial_value && chaining_value != NULL) {
    980        PORT_ZFree(chaining_value, chaining_length);
    981    }
    982 
    983    return ret;
    984 }
    985 
    986 static CK_RV
    987 kbkdf_PipelineRaw(const CK_SP800_108_KDF_PARAMS *params, sftk_MACCtx *ctx, unsigned char *ret_buffer, size_t buffer_length, PRUint64 output_bitlen)
    988 {
    989    CK_RV ret = CKR_OK;
    990 
    991    /* Counter variable for this KDF instance. */
    992    PRUint32 counter;
    993 
    994    /* Number of iterations required of this PRF necessary to reach the
    995     * desired output length. */
    996    PRUint32 num_iterations;
    997 
    998    /* Offset in ret_buffer that we're at. */
    999    size_t buffer_offset = 0;
   1000 
   1001    /* Size of this block, in bytes. Defaults to ctx->mac_size except on
   1002     * the last iteration where it could be a partial block. */
   1003    size_t block_size = ctx->mac_size;
   1004 
   1005    /* The last PRF invocation. This is used for the first of the double
   1006     * PRF invocations this KDF is named after. This defaults to NULL,
   1007     * signifying that we have to calculate the initial value from params;
   1008     * when non-NULL, we directly add only this value to the PRF. */
   1009    unsigned char *chaining_value = NULL;
   1010 
   1011    /* Size of the chaining value discussed above. Defaults to 0. */
   1012    size_t chaining_length = 0;
   1013 
   1014    /* Calculate the number of iterations required based on the size of the
   1015     * output buffer. */
   1016    ret = kbkdf_CalculateIterations(CKM_SP800_108_DOUBLE_PIPELINE_KDF, params, ctx, buffer_length, &num_iterations);
   1017    if (ret != CKR_OK) {
   1018        goto finish;
   1019    }
   1020 
   1021    /*
   1022     * 5.3 - [ KDF in Double-Pipeline Iteration Mode ]
   1023     *
   1024     * Fixed values:
   1025     *      1. h - the length of the PRF in bits (ctx->mac_size)
   1026     *      2. r - the length of the binary representation of the counter i
   1027     *          (params[k: params[k].type == CK_SP800_108_OPTIONAL_COUNTER:].data->ulWidthInBits)
   1028     *          Note that it is only specified when the optional counter is requested.
   1029     * Input:
   1030     *      1. K_I - the key for the PRF (base_key)
   1031     *      2. label - a binary data field, usually before the separator. Optional.
   1032     *      3. context - a binary data field, usually after the separator. Optional.
   1033     *      4. L - length of the output in bits (output_bitlen)
   1034     *
   1035     * Process:
   1036     *      1. n := ceil(L / h) (num_iterations)
   1037     *      2. if n > 2^32 - 1, then indicate an error and stop
   1038     *      3. result(0) = NULL
   1039     *      4. A(0) := IV := Label || 0x00 || Context || [L]_2
   1040     *      5. for i = 1 to n, do
   1041     *          a. A(i) := PRF(K_I, A(i-1))
   1042     *          b. K(i) := PRF(K_I, A(i) {|| [i]_2} || Label || 0x00 || Context || [L]_2
   1043     *          c. result(i) := result(i-1) || K(i)
   1044     *      6. return K_O := the leftmost L bits of result(n).
   1045     */
   1046    for (counter = 1; counter <= num_iterations; counter++) {
   1047        if (counter == num_iterations) {
   1048            block_size = buffer_length - buffer_offset;
   1049 
   1050            /* Assumption: if we've validated our arguments correctly, this
   1051             * should always be true. */
   1052            PR_ASSERT(block_size <= ctx->mac_size);
   1053        }
   1054 
   1055        /* ===== First pipeline: construct A(i) ===== */
   1056        if (counter == 1) {
   1057            /* On the first iteration, we have no chaining value so specify
   1058             * NULL for the pointer and 0 for the length, and exclude the
   1059             * optional counter if it exists. This is what NIST specifies as
   1060             * the IV for the KDF. */
   1061            ret = kbkdf_AddParameters(CKM_SP800_108_DOUBLE_PIPELINE_KDF, ctx, params, counter, output_bitlen, NULL, 0, CK_SP800_108_OPTIONAL_COUNTER);
   1062            if (ret != CKR_OK) {
   1063                goto finish;
   1064            }
   1065 
   1066            /* Allocate the chaining value so we can save the PRF output. */
   1067            chaining_value = PORT_ZNewArray(unsigned char, ctx->mac_size);
   1068            chaining_length = ctx->mac_size;
   1069            if (chaining_value == NULL) {
   1070                ret = CKR_HOST_MEMORY;
   1071                goto finish;
   1072            }
   1073        } else {
   1074            /* On all other iterations, the next stage of the first pipeline
   1075             * comes directly from this stage. */
   1076            ret = sftk_MAC_Update(ctx, chaining_value, chaining_length);
   1077            if (ret != CKR_OK) {
   1078                goto finish;
   1079            }
   1080        }
   1081 
   1082        /* Save the PRF output to chaining_value for use in the second
   1083         * pipeline. */
   1084        ret = sftk_MAC_End(ctx, chaining_value, NULL, chaining_length);
   1085        if (ret != CKR_OK) {
   1086            goto finish;
   1087        }
   1088 
   1089        /* Reset the PRF so we can reuse it for the second pipeline. */
   1090        ret = sftk_MAC_Reset(ctx);
   1091        if (ret != CKR_OK) {
   1092            goto finish;
   1093        }
   1094 
   1095        /* ===== Second pipeline: construct K(i) ===== */
   1096 
   1097        /* Add all parameters required by this instance of the KDF to the
   1098         * input stream of the underlying PRF. Note that this includes the
   1099         * chaining value we calculated from the previous pipeline stage. */
   1100        ret = kbkdf_AddParameters(CKM_SP800_108_FEEDBACK_KDF, ctx, params, counter, output_bitlen, chaining_value, chaining_length, 0 /* exclude */);
   1101        if (ret != CKR_OK) {
   1102            goto finish;
   1103        }
   1104 
   1105        /* Finalize this iteration of the PRF directly to the output buffer.
   1106         * Unlike Feedback mode, this pipeline doesn't influence the previous
   1107         * stage. */
   1108        ret = sftk_MAC_End(ctx, ret_buffer + buffer_offset, NULL, block_size);
   1109        if (ret != CKR_OK) {
   1110            goto finish;
   1111        }
   1112 
   1113        /* Increment our position in the key material. */
   1114        buffer_offset += block_size;
   1115 
   1116        if (counter < num_iterations) {
   1117            /* Reset the underlying PRF for the next iteration. Only do this
   1118             * when we have a next iteration since it isn't necessary to do
   1119             * either before the first iteration (MAC is already initialized)
   1120             * or after the last iteration (we won't be called again). */
   1121            ret = sftk_MAC_Reset(ctx);
   1122            if (ret != CKR_OK) {
   1123                goto finish;
   1124            }
   1125        }
   1126    }
   1127 
   1128 finish:
   1129    PORT_ZFree(chaining_value, chaining_length);
   1130 
   1131    return ret;
   1132 }
   1133 
   1134 static CK_RV
   1135 kbkdf_RawDispatch(CK_MECHANISM_TYPE mech,
   1136                  const CK_SP800_108_KDF_PARAMS *kdf_params,
   1137                  const CK_BYTE *initial_value,
   1138                  CK_ULONG initial_value_length,
   1139                  SFTKObject *prf_key, const unsigned char *prf_key_bytes,
   1140                  unsigned int prf_key_length, unsigned char **out_key_bytes,
   1141                  size_t *out_key_length, unsigned int *mac_size,
   1142                  CK_ULONG ret_key_size)
   1143 {
   1144    CK_RV ret;
   1145    /* Context for our underlying PRF function.
   1146     *
   1147     * Zeroing context required unconditional call of sftk_MAC_DestroyContext.
   1148     */
   1149    sftk_MACCtx ctx = { 0 };
   1150 
   1151    /* We need one buffers large enough to fit the entire KDF key stream for
   1152     * all iterations of the PRF. This needs only include to the end of the
   1153     * last key, so it isn't an even multiple of the PRF output size. */
   1154    unsigned char *output_buffer = NULL;
   1155 
   1156    /* Size of the above buffer, in bytes. Note that this is technically
   1157     * separate from the below output_bitlen variable due to the presence
   1158     * of additional derived keys. See commentary in kbkdf_CalculateLength.
   1159     */
   1160    size_t buffer_length = 0;
   1161 
   1162    /* While NIST specifies a maximum length (in bits) for the counter, they
   1163     * don't for the maximum length. It is unlikely, but theoretically
   1164     * possible for output of the PRF to exceed 32 bits while keeping the
   1165     * counter under 2^32. Thus, use a 64-bit variable for the maximum
   1166     * output length.
   1167     *
   1168     * It is unlikely any caller will request this much data in practice.
   1169     * 2^32 invocations of the PRF (for a 512-bit PRF) would be 256GB of
   1170     * data in the KDF key stream alone. The bigger limit is the number of
   1171     * and size of keys (again, 2^32); this could easily exceed 256GB when
   1172     * counting the backing softoken key, the key data, template data, and
   1173     * the input parameters to this KDF.
   1174     *
   1175     * This is the L parameter in NIST SP800-108.
   1176     */
   1177    PRUint64 output_bitlen = 0;
   1178 
   1179    /* First validate our passed input parameters against PKCS#11 v3.0
   1180     * and NIST SP800-108 requirements. */
   1181    ret = kbkdf_ValidateParameters(mech, kdf_params, ret_key_size);
   1182    if (ret != CKR_OK) {
   1183        goto finish;
   1184    }
   1185 
   1186    /* Initialize the underlying PRF state. */
   1187    if (prf_key) {
   1188        ret = sftk_MAC_Init(&ctx, kdf_params->prfType, prf_key);
   1189    } else {
   1190        ret = sftk_MAC_InitRaw(&ctx, kdf_params->prfType, prf_key_bytes,
   1191                               prf_key_length, PR_TRUE);
   1192    }
   1193    if (ret != CKR_OK) {
   1194        goto finish;
   1195    }
   1196 
   1197    /* Compute the size of our output buffer based on passed parameters and
   1198     * the output size of the underlying PRF. */
   1199    ret = kbkdf_CalculateLength(kdf_params, &ctx, ret_key_size, &output_bitlen, &buffer_length);
   1200    if (ret != CKR_OK) {
   1201        goto finish;
   1202    }
   1203 
   1204    /* Allocate memory for the PRF output */
   1205    output_buffer = PORT_ZNewArray(unsigned char, buffer_length);
   1206    if (output_buffer == NULL) {
   1207        ret = CKR_HOST_MEMORY;
   1208        goto finish;
   1209    }
   1210 
   1211    /* Call into the underlying KDF */
   1212    switch (mech) {
   1213        case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA: /* fall through */
   1214        case CKM_SP800_108_COUNTER_KDF:
   1215            ret = kbkdf_CounterRaw(kdf_params, &ctx, output_buffer, buffer_length, output_bitlen);
   1216            break;
   1217        case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA: /* fall through */
   1218        case CKM_SP800_108_FEEDBACK_KDF:
   1219            ret = kbkdf_FeedbackRaw(kdf_params, initial_value, initial_value_length, &ctx, output_buffer, buffer_length, output_bitlen);
   1220            break;
   1221        case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA: /* fall through */
   1222        case CKM_SP800_108_DOUBLE_PIPELINE_KDF:
   1223            ret = kbkdf_PipelineRaw(kdf_params, &ctx, output_buffer, buffer_length, output_bitlen);
   1224            break;
   1225        default:
   1226            /* Shouldn't happen unless NIST introduces a new KBKDF type. */
   1227            PR_ASSERT(PR_FALSE);
   1228            ret = CKR_FUNCTION_FAILED;
   1229    }
   1230 
   1231    /* Validate the above KDF succeeded. */
   1232    if (ret != CKR_OK) {
   1233        goto finish;
   1234    }
   1235 
   1236    *out_key_bytes = output_buffer;
   1237    *out_key_length = buffer_length;
   1238    *mac_size = ctx.mac_size;
   1239 
   1240    output_buffer = NULL; /* returning the buffer, don't zero and free it */
   1241 
   1242 finish:
   1243    PORT_ZFree(output_buffer, buffer_length);
   1244 
   1245    /* Free the PRF. This should handle clearing all sensitive information. */
   1246    sftk_MAC_DestroyContext(&ctx, PR_FALSE);
   1247    return ret;
   1248 }
   1249 
   1250 /* [ section: PKCS#11 entry ] */
   1251 
   1252 CK_RV
   1253 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)
   1254 {
   1255    /* This handles boilerplate common to all KBKDF types. Instead of placing
   1256     * this in pkcs11c.c, place it here to reduce clutter. */
   1257 
   1258    CK_RV ret;
   1259 
   1260    /* Assumptions about our calling environment. */
   1261    PR_ASSERT(pMechanism != NULL && prf_key != NULL && ret_key != NULL);
   1262 
   1263    /* Validate that the caller passed parameters. */
   1264    if (pMechanism->pParameter == NULL) {
   1265        return CKR_MECHANISM_PARAM_INVALID;
   1266    }
   1267 
   1268    /* Create a common set of parameters to use for all KDF types. This
   1269     * separates out the KDF parameters from the Feedback-specific IV,
   1270     * allowing us to use a common type for all calls. */
   1271    CK_SP800_108_KDF_PARAMS kdf_params = { 0 };
   1272    CK_BYTE_PTR initial_value = NULL;
   1273    CK_ULONG initial_value_length = 0;
   1274    unsigned char *output_buffer = NULL;
   1275    size_t buffer_length = 0;
   1276    unsigned int mac_size = 0;
   1277 
   1278    /* Split Feedback-specific IV from remaining KDF parameters. */
   1279    ret = kbkdf_LoadParameters(mech, pMechanism, &kdf_params, &initial_value, &initial_value_length);
   1280    if (ret != CKR_OK) {
   1281        goto finish;
   1282    }
   1283    /* let rawDispatch handle the rest. We split this out so we could
   1284     * handle the POST test without accessing pkcs #11 objects. */
   1285    ret = kbkdf_RawDispatch(mech, &kdf_params, initial_value,
   1286                            initial_value_length, prf_key, NULL, 0,
   1287                            &output_buffer, &buffer_length, &mac_size,
   1288                            ret_key_size);
   1289    if (ret != CKR_OK) {
   1290        goto finish;
   1291    }
   1292 
   1293    /* Write the output of the PRF into the appropriate keys. */
   1294    ret = kbkdf_SaveKeys(mech, hSession, &kdf_params, output_buffer, buffer_length, mac_size, ret_key, ret_key_size);
   1295    if (ret != CKR_OK) {
   1296        goto finish;
   1297    }
   1298 
   1299 finish:
   1300    PORT_ZFree(output_buffer, buffer_length);
   1301 
   1302    return ret;
   1303 }
   1304 
   1305 struct sftk_SP800_Test_struct {
   1306    CK_MECHANISM_TYPE mech;
   1307    CK_SP800_108_KDF_PARAMS kdf_params;
   1308    unsigned int expected_mac_size;
   1309    unsigned int ret_key_length;
   1310    const unsigned char expected_key_bytes[64];
   1311 };
   1312 
   1313 static const CK_SP800_108_COUNTER_FORMAT counter_32 = { 0, 32 };
   1314 static const CK_PRF_DATA_PARAM counter_32_data = { CK_SP800_108_ITERATION_VARIABLE, (CK_VOID_PTR)&counter_32, sizeof(counter_32) };
   1315 
   1316 #ifdef NSS_FULL_POST
   1317 static const CK_SP800_108_COUNTER_FORMAT counter_16 = { 0, 16 };
   1318 static const CK_PRF_DATA_PARAM counter_16_data = { CK_SP800_108_ITERATION_VARIABLE, (CK_VOID_PTR)&counter_16, sizeof(counter_16) };
   1319 static const CK_PRF_DATA_PARAM counter_null_data = { CK_SP800_108_ITERATION_VARIABLE, NULL, 0 };
   1320 #endif
   1321 
   1322 static const struct sftk_SP800_Test_struct sftk_SP800_Tests[] = {
   1323 #ifdef NSS_FULL_POST
   1324    {
   1325        CKM_SP800_108_COUNTER_KDF,
   1326        { CKM_AES_CMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_16_data, 0, NULL },
   1327        16,
   1328        64,
   1329        { 0x7b, 0x1c, 0xe7, 0xf3, 0x14, 0x67, 0x15, 0xdd,
   1330          0xde, 0x0c, 0x09, 0x46, 0x3f, 0x47, 0x7b, 0xa6,
   1331          0xb8, 0xba, 0x40, 0x07, 0x7c, 0xe3, 0x19, 0x53,
   1332          0x26, 0xac, 0x4c, 0x2e, 0x2b, 0x37, 0x41, 0xe4,
   1333          0x1b, 0x01, 0x3f, 0x2f, 0x2d, 0x16, 0x95, 0xee,
   1334          0xeb, 0x7e, 0x72, 0x7d, 0xa4, 0xab, 0x2e, 0x67,
   1335          0x1d, 0xef, 0x6f, 0xa2, 0xc6, 0xee, 0x3c, 0xcf,
   1336          0xef, 0x88, 0xfd, 0x5c, 0x1d, 0x7b, 0xa0, 0x5a },
   1337    },
   1338    {
   1339        CKM_SP800_108_COUNTER_KDF,
   1340        { CKM_SHA384_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_32_data, 0, NULL },
   1341        48,
   1342        64,
   1343        { 0xe6, 0x62, 0xa4, 0x32, 0x5c, 0xe4, 0xc2, 0x28,
   1344          0x73, 0x8a, 0x5d, 0x94, 0xe7, 0x05, 0xe0, 0x5a,
   1345          0x71, 0x61, 0xb2, 0x3c, 0x51, 0x28, 0x03, 0x1d,
   1346          0xa7, 0xf5, 0x10, 0x83, 0x34, 0xdb, 0x11, 0x73,
   1347          0x92, 0xa6, 0x79, 0x74, 0x81, 0x5d, 0x22, 0x7e,
   1348          0x8d, 0xf2, 0x59, 0x14, 0x56, 0x60, 0xcf, 0xb2,
   1349          0xb3, 0xfd, 0x46, 0xfd, 0x9b, 0x74, 0xfe, 0x4a,
   1350          0x09, 0x30, 0x4a, 0xdf, 0x07, 0x43, 0xfe, 0x85 },
   1351    },
   1352    {
   1353        CKM_SP800_108_COUNTER_KDF,
   1354        { CKM_SHA512_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_32_data, 0, NULL },
   1355        64,
   1356        64,
   1357        { 0xb0, 0x78, 0x36, 0xe1, 0x15, 0xd6, 0xf0, 0xac,
   1358          0x68, 0x7b, 0x42, 0xd3, 0xb6, 0x82, 0x51, 0xad,
   1359          0x95, 0x0a, 0x69, 0x88, 0x84, 0xc2, 0x2e, 0x07,
   1360          0x34, 0x62, 0x8d, 0x42, 0x72, 0x0f, 0x22, 0xe6,
   1361          0xd5, 0x7f, 0x80, 0x15, 0xe6, 0x84, 0x00, 0x65,
   1362          0xef, 0x64, 0x77, 0x29, 0xd6, 0x3b, 0xc7, 0x9a,
   1363          0x15, 0x6d, 0x36, 0xf3, 0x96, 0xc9, 0x14, 0x3f,
   1364          0x2d, 0x4a, 0x7c, 0xdb, 0xc3, 0x6c, 0x3d, 0x6a },
   1365    },
   1366    {
   1367        CKM_SP800_108_FEEDBACK_KDF,
   1368        { CKM_AES_CMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1369        16,
   1370        64,
   1371        { 0xc0, 0xa0, 0x23, 0x96, 0x16, 0x4d, 0xd6, 0xbd,
   1372          0x2a, 0x75, 0x8e, 0x72, 0xf5, 0xc3, 0xa0, 0xb8,
   1373          0x78, 0x83, 0x15, 0x21, 0x34, 0xd3, 0xd8, 0x71,
   1374          0xc9, 0xe7, 0x4b, 0x20, 0xb7, 0x65, 0x5b, 0x13,
   1375          0xbc, 0x85, 0x54, 0xe3, 0xb6, 0xee, 0x73, 0xd5,
   1376          0xf2, 0xa0, 0x94, 0x1a, 0x79, 0x66, 0x3b, 0x1e,
   1377          0x67, 0x3e, 0x69, 0xa4, 0x12, 0x40, 0xa9, 0xda,
   1378          0x8d, 0x14, 0xb1, 0xce, 0xf1, 0x4b, 0x79, 0x4e },
   1379    },
   1380    {
   1381        CKM_SP800_108_FEEDBACK_KDF,
   1382        { CKM_SHA256_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1383        32,
   1384        64,
   1385        { 0x99, 0x9b, 0x08, 0x79, 0x14, 0x2e, 0x58, 0x34,
   1386          0xd7, 0x92, 0xa7, 0x7e, 0x7f, 0xc2, 0xf0, 0x34,
   1387          0xa3, 0x4e, 0x33, 0xf0, 0x63, 0x95, 0x2d, 0xad,
   1388          0xbf, 0x3b, 0xcb, 0x6d, 0x4e, 0x07, 0xd9, 0xe9,
   1389          0xbd, 0xbd, 0x77, 0x54, 0xe1, 0xa3, 0x36, 0x26,
   1390          0xcd, 0xb1, 0xf9, 0x2d, 0x80, 0x68, 0xa2, 0x01,
   1391          0x4e, 0xbf, 0x35, 0xec, 0x65, 0xae, 0xfd, 0x71,
   1392          0xa6, 0xd7, 0x62, 0x26, 0x2c, 0x3f, 0x73, 0x63 },
   1393    },
   1394    {
   1395        CKM_SP800_108_FEEDBACK_KDF,
   1396        { CKM_SHA384_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1397        48,
   1398        64,
   1399        { 0xc8, 0x7a, 0xf8, 0xd9, 0x6b, 0x90, 0x82, 0x35,
   1400          0xea, 0xf5, 0x2c, 0x8f, 0xce, 0xaa, 0x3b, 0xa5,
   1401          0x68, 0xd3, 0x7f, 0xae, 0x31, 0x93, 0xe6, 0x69,
   1402          0x0c, 0xd1, 0x74, 0x7f, 0x8f, 0xc2, 0xe2, 0x33,
   1403          0x93, 0x45, 0x23, 0xba, 0xb3, 0x73, 0xc9, 0x2c,
   1404          0xd6, 0xd2, 0x10, 0x16, 0xe9, 0x9f, 0x9e, 0xe8,
   1405          0xc1, 0x0e, 0x29, 0x95, 0x3d, 0x16, 0x68, 0x24,
   1406          0x40, 0x4d, 0x40, 0x21, 0x41, 0xa6, 0xc8, 0xdb },
   1407    },
   1408    {
   1409        CKM_SP800_108_FEEDBACK_KDF,
   1410        { CKM_SHA512_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1411        64,
   1412        64,
   1413        { 0x81, 0x39, 0x12, 0xc2, 0xf9, 0x31, 0x24, 0x7c,
   1414          0x71, 0x12, 0x97, 0x08, 0x82, 0x76, 0x83, 0x55,
   1415          0x8c, 0x82, 0xf3, 0x09, 0xd6, 0x1b, 0x7a, 0xa2,
   1416          0x6e, 0x71, 0x6b, 0xad, 0x46, 0x57, 0x60, 0x89,
   1417          0x38, 0xcf, 0x63, 0xfa, 0xf4, 0x38, 0x27, 0xef,
   1418          0xf0, 0xaf, 0x75, 0x4e, 0xc2, 0xe0, 0x31, 0xdb,
   1419          0x59, 0x7d, 0x19, 0xc9, 0x6d, 0xbb, 0xed, 0x95,
   1420          0xaf, 0x3e, 0xd8, 0x33, 0x76, 0xab, 0xec, 0xfa },
   1421    },
   1422    {
   1423        CKM_SP800_108_DOUBLE_PIPELINE_KDF,
   1424        { CKM_AES_CMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1425        16,
   1426        64,
   1427        { 0x3e, 0xa8, 0xbf, 0x77, 0x84, 0x90, 0xb0, 0x3a,
   1428          0x89, 0x16, 0x32, 0x01, 0x92, 0xd3, 0x1f, 0x1b,
   1429          0xc1, 0x06, 0xc5, 0x32, 0x62, 0x03, 0x50, 0x16,
   1430          0x3b, 0xb9, 0xa7, 0xdc, 0xb5, 0x68, 0x6a, 0xbb,
   1431          0xbb, 0x7d, 0x63, 0x69, 0x24, 0x6e, 0x09, 0xd6,
   1432          0x6f, 0x80, 0x57, 0x65, 0xc5, 0x62, 0x33, 0x96,
   1433          0x69, 0xe6, 0xab, 0x65, 0x36, 0xd0, 0xe2, 0x5c,
   1434          0xd7, 0xbd, 0xe4, 0x68, 0x13, 0xd6, 0xb1, 0x46 },
   1435    },
   1436    {
   1437        CKM_SP800_108_DOUBLE_PIPELINE_KDF,
   1438        { CKM_SHA256_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1439        32,
   1440        64,
   1441        { 0xeb, 0x28, 0xd9, 0x2c, 0x19, 0x33, 0xb9, 0x2a,
   1442          0xf9, 0xac, 0x85, 0xbd, 0xf4, 0xdb, 0xfa, 0x88,
   1443          0x73, 0xf4, 0x36, 0x08, 0xdb, 0xfe, 0x13, 0xd1,
   1444          0x5a, 0xec, 0x7b, 0x68, 0x13, 0x53, 0xb3, 0xd1,
   1445          0x31, 0xf2, 0x83, 0xae, 0x9f, 0x75, 0x47, 0xb6,
   1446          0x6d, 0x3c, 0x20, 0x16, 0x47, 0x9c, 0x27, 0x66,
   1447          0xec, 0xa9, 0xdf, 0x0c, 0xda, 0x2a, 0xf9, 0xf4,
   1448          0x55, 0x74, 0xde, 0x9d, 0x3f, 0xe3, 0x5e, 0x14 },
   1449    },
   1450    {
   1451        CKM_SP800_108_DOUBLE_PIPELINE_KDF,
   1452        { CKM_SHA384_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1453        48,
   1454        64,
   1455        { 0xa5, 0xca, 0x32, 0x40, 0x00, 0x93, 0xb2, 0xcc,
   1456          0x78, 0x3c, 0xa6, 0xc4, 0xaf, 0xa8, 0xb3, 0xd0,
   1457          0xa4, 0x6b, 0xb5, 0x31, 0x35, 0x87, 0x33, 0xa2,
   1458          0x6a, 0x6b, 0xe1, 0xff, 0xea, 0x1d, 0x6e, 0x9e,
   1459          0x0b, 0xde, 0x8b, 0x92, 0x15, 0xd6, 0x56, 0x2f,
   1460          0xb6, 0x1a, 0xd7, 0xd2, 0x01, 0x3e, 0x28, 0x2e,
   1461          0xfa, 0x84, 0x3c, 0xc0, 0xe8, 0xbe, 0x94, 0xc0,
   1462          0x06, 0xbd, 0xbf, 0x87, 0x1f, 0xb8, 0x64, 0xc2 },
   1463    },
   1464    {
   1465        CKM_SP800_108_DOUBLE_PIPELINE_KDF,
   1466        { CKM_SHA512_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_null_data, 0, NULL },
   1467        64,
   1468        64,
   1469        { 0x3f, 0xd9, 0x4e, 0x80, 0x58, 0x21, 0xc8, 0xea,
   1470          0x22, 0x17, 0xcf, 0x7d, 0xce, 0xfd, 0xec, 0x03,
   1471          0xb9, 0xe4, 0xa2, 0xf7, 0xc0, 0xf1, 0x68, 0x81,
   1472          0x53, 0x71, 0xb7, 0x42, 0x14, 0x4e, 0x5b, 0x09,
   1473          0x05, 0x31, 0xb9, 0x27, 0x18, 0x2d, 0x23, 0xf8,
   1474          0x9c, 0x3d, 0x4e, 0xd0, 0xdd, 0xf3, 0x1e, 0x4b,
   1475          0xf2, 0xf9, 0x1a, 0x5d, 0x00, 0x66, 0x22, 0x83,
   1476          0xae, 0x3c, 0x53, 0xd2, 0x54, 0x4b, 0x06, 0x4c },
   1477    },
   1478 #endif
   1479    {
   1480        CKM_SP800_108_COUNTER_KDF,
   1481        { CKM_SHA256_HMAC, 1, (CK_PRF_DATA_PARAM_PTR)&counter_32_data, 0, NULL },
   1482        32,
   1483        64,
   1484        { 0xfb, 0x2b, 0xb5, 0xde, 0xce, 0x5a, 0x2b, 0xdc,
   1485          0x25, 0x8f, 0x54, 0x17, 0x4b, 0x5a, 0xa7, 0x90,
   1486          0x64, 0x36, 0xeb, 0x43, 0x1f, 0x1d, 0xf9, 0x23,
   1487          0xb2, 0x22, 0x29, 0xa0, 0xfa, 0x2e, 0x21, 0xb6,
   1488          0xb7, 0xfb, 0x27, 0x0a, 0x1c, 0xa6, 0x58, 0x43,
   1489          0xa1, 0x16, 0x44, 0x29, 0x4b, 0x1c, 0xb3, 0x72,
   1490          0xd5, 0x98, 0x9d, 0x27, 0xd5, 0x75, 0x25, 0xbf,
   1491          0x23, 0x61, 0x40, 0x48, 0xbb, 0x0b, 0x49, 0x8e },
   1492    }
   1493 };
   1494 
   1495 SECStatus
   1496 sftk_fips_SP800_108_PowerUpSelfTests(void)
   1497 {
   1498    int i;
   1499    CK_RV crv;
   1500 
   1501    const unsigned char prf_key[] = {
   1502        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
   1503        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
   1504        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
   1505        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
   1506        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
   1507        0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
   1508        0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
   1509        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78
   1510    };
   1511    for (i = 0; i < PR_ARRAY_SIZE(sftk_SP800_Tests); i++) {
   1512        const struct sftk_SP800_Test_struct *test = &sftk_SP800_Tests[i];
   1513        unsigned char *output_buffer;
   1514        size_t buffer_length;
   1515        unsigned int mac_size;
   1516 
   1517        crv = kbkdf_RawDispatch(test->mech, &test->kdf_params,
   1518                                prf_key, test->expected_mac_size,
   1519                                NULL, prf_key, test->expected_mac_size,
   1520                                &output_buffer, &buffer_length, &mac_size,
   1521                                test->ret_key_length);
   1522        if (crv != CKR_OK) {
   1523            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   1524            return SECFailure;
   1525        }
   1526        if ((mac_size != test->expected_mac_size) ||
   1527            (buffer_length != test->ret_key_length) ||
   1528            (output_buffer == NULL) ||
   1529            (PORT_Memcmp(output_buffer, test->expected_key_bytes, buffer_length) != 0)) {
   1530            PORT_ZFree(output_buffer, buffer_length);
   1531            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   1532            return SECFailure;
   1533        }
   1534        PORT_ZFree(output_buffer, buffer_length);
   1535    }
   1536    return SECSuccess;
   1537 }