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