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