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