Merge pull request #7700 from silabs-Kusumit/PBKDF2_output_bytes
PBKDF2: Output bytes
This commit is contained in:
commit
f45a5a0ddd
5 changed files with 227 additions and 14 deletions
|
@ -5474,6 +5474,137 @@ static psa_status_t psa_key_derivation_tls12_ecjpake_to_pms_read(
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
|
||||
static psa_status_t psa_key_derivation_pbkdf2_generate_block(
|
||||
psa_pbkdf2_key_derivation_t *pbkdf2,
|
||||
psa_algorithm_t prf_alg,
|
||||
uint8_t prf_output_length,
|
||||
psa_key_attributes_t *attributes)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT;
|
||||
size_t mac_output_length;
|
||||
uint8_t U_i[PSA_MAC_MAX_SIZE];
|
||||
uint8_t *U_accumulator = pbkdf2->output_block;
|
||||
uint64_t i;
|
||||
uint8_t block_counter[4];
|
||||
|
||||
mac_operation.is_sign = 1;
|
||||
mac_operation.mac_size = prf_output_length;
|
||||
MBEDTLS_PUT_UINT32_BE(pbkdf2->block_number, block_counter, 0);
|
||||
|
||||
status = psa_driver_wrapper_mac_sign_setup(&mac_operation,
|
||||
attributes,
|
||||
pbkdf2->password,
|
||||
pbkdf2->password_length,
|
||||
prf_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
status = psa_mac_update(&mac_operation, pbkdf2->salt, pbkdf2->salt_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
status = psa_mac_update(&mac_operation, block_counter, sizeof(block_counter));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
status = psa_mac_sign_finish(&mac_operation, U_i, sizeof(U_i),
|
||||
&mac_output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (mac_output_length != prf_output_length) {
|
||||
status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(U_accumulator, U_i, prf_output_length);
|
||||
|
||||
for (i = 1; i < pbkdf2->input_cost; i++) {
|
||||
status = psa_driver_wrapper_mac_compute(attributes,
|
||||
pbkdf2->password,
|
||||
pbkdf2->password_length,
|
||||
prf_alg, U_i, prf_output_length,
|
||||
U_i, sizeof(U_i),
|
||||
&mac_output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
mbedtls_xor(U_accumulator, U_accumulator, U_i, prf_output_length);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* Zeroise buffers to clear sensitive data from memory. */
|
||||
mbedtls_platform_zeroize(U_i, PSA_MAC_MAX_SIZE);
|
||||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t psa_key_derivation_pbkdf2_read(
|
||||
psa_pbkdf2_key_derivation_t *pbkdf2,
|
||||
psa_algorithm_t kdf_alg,
|
||||
uint8_t *output,
|
||||
size_t output_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_algorithm_t prf_alg;
|
||||
uint8_t prf_output_length;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(pbkdf2->password_length));
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
|
||||
|
||||
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
|
||||
prf_alg = PSA_ALG_HMAC(PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg));
|
||||
prf_output_length = PSA_HASH_LENGTH(prf_alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
|
||||
} else {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
switch (pbkdf2->state) {
|
||||
case PSA_PBKDF2_STATE_PASSWORD_SET:
|
||||
/* Initially we need a new block so bytes_used is equal to block size*/
|
||||
pbkdf2->bytes_used = prf_output_length;
|
||||
pbkdf2->state = PSA_PBKDF2_STATE_OUTPUT;
|
||||
break;
|
||||
case PSA_PBKDF2_STATE_OUTPUT:
|
||||
break;
|
||||
default:
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
while (output_length != 0) {
|
||||
uint8_t n = prf_output_length - pbkdf2->bytes_used;
|
||||
if (n > output_length) {
|
||||
n = (uint8_t) output_length;
|
||||
}
|
||||
memcpy(output, pbkdf2->output_block + pbkdf2->bytes_used, n);
|
||||
output += n;
|
||||
output_length -= n;
|
||||
pbkdf2->bytes_used += n;
|
||||
|
||||
if (output_length == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* We need a new block */
|
||||
pbkdf2->bytes_used = 0;
|
||||
pbkdf2->block_number++;
|
||||
|
||||
status = psa_key_derivation_pbkdf2_generate_block(pbkdf2, prf_alg,
|
||||
prf_output_length,
|
||||
&attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
|
||||
|
||||
psa_status_t psa_key_derivation_output_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
uint8_t *output,
|
||||
|
@ -5529,11 +5660,8 @@ psa_status_t psa_key_derivation_output_bytes(
|
|||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
|
||||
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
|
||||
/* As output functionality is not added yet return
|
||||
* PSA_ERROR_NOT_SUPPORTED for now if inputs are passed correctly.
|
||||
* If input validation fails operation is aborted and output_bytes
|
||||
* will return PSA_ERROR_BAD_STATE */
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
status = psa_key_derivation_pbkdf2_read(&operation->ctx.pbkdf2, kdf_alg,
|
||||
output, output_length);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue