Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions src/psa_key_derivation.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,24 @@ static int wolfpsa_hash_type_from_alg(psa_algorithm_t alg)
}
}

#if defined(WOLFSSL_HAVE_PRF) && !defined(NO_HMAC)
/* wc_PRF_TLS wants a wc_MACAlgorithm id and promotes ids below sha256_mac to
* SHA-256, so only map SHA-256/384/512; others return no_mac (caller rejects). */
static int wolfpsa_prf_mac_from_alg(psa_algorithm_t alg)
{
switch (wolfpsa_hash_type_from_alg(alg)) {
case WC_HASH_TYPE_SHA256:
return sha256_mac;
case WC_HASH_TYPE_SHA384:
return sha384_mac;
case WC_HASH_TYPE_SHA512:
return sha512_mac;
default:
return no_mac;
}
}
#endif

static psa_status_t wolfpsa_kdf_require_output(wolfpsa_kdf_ctx_t *ctx,
size_t output_length)
{
Expand Down Expand Up @@ -962,9 +980,10 @@ static psa_status_t wolfpsa_kdf_tls12_prf(wolfpsa_kdf_ctx_t *ctx,
return PSA_ERROR_NOT_SUPPORTED;
#else
int hash_type = wolfpsa_hash_type_from_alg(ctx->alg);
int prf_mac = wolfpsa_prf_mac_from_alg(ctx->alg);
int ret;

if (hash_type == WC_HASH_TYPE_NONE) {
if (hash_type == WC_HASH_TYPE_NONE || prf_mac == no_mac) {
return PSA_ERROR_NOT_SUPPORTED;
}
if ((wolfpsa_check_word32_length(output_length) != PSA_SUCCESS) ||
Expand All @@ -977,7 +996,8 @@ static psa_status_t wolfpsa_kdf_tls12_prf(wolfpsa_kdf_ctx_t *ctx,
ctx->secret, (word32)ctx->secret_length,
ctx->label, (word32)ctx->label_length,
ctx->seed, (word32)ctx->seed_length,
1, hash_type, NULL, wolfPSA_GetDefaultDevID());
1, prf_mac, NULL,
wolfPSA_GetDefaultDevID());
if (ret != 0) {
return wc_error_to_psa_status(ret);
}
Expand All @@ -996,14 +1016,15 @@ static psa_status_t wolfpsa_kdf_tls12_psk_to_ms(wolfpsa_kdf_ctx_t *ctx,
return PSA_ERROR_NOT_SUPPORTED;
#else
int hash_type = wolfpsa_hash_type_from_alg(ctx->alg);
int prf_mac = wolfpsa_prf_mac_from_alg(ctx->alg);
size_t other_secret_length;
const uint8_t *other_secret;
uint8_t *premaster = NULL;
size_t premaster_len;
psa_status_t status;
int ret;

if (hash_type == WC_HASH_TYPE_NONE) {
if (hash_type == WC_HASH_TYPE_NONE || prf_mac == no_mac) {
return PSA_ERROR_NOT_SUPPORTED;
}
if ((ctx->steps_set & WOLFPSA_KDF_STEP_OTHER_SECRET) == 0) {
Expand Down Expand Up @@ -1043,7 +1064,8 @@ static psa_status_t wolfpsa_kdf_tls12_psk_to_ms(wolfpsa_kdf_ctx_t *ctx,
premaster, (word32)premaster_len,
(const byte *)"master secret", 13u,
ctx->seed, (word32)ctx->seed_length,
1, hash_type, NULL, wolfPSA_GetDefaultDevID());
1, prf_mac, NULL,
wolfPSA_GetDefaultDevID());
if (ret != 0) {
status = wc_error_to_psa_status(ret);
}
Expand Down
75 changes: 73 additions & 2 deletions test/psa_server/psa_api_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -7835,7 +7835,7 @@ static int test_kdf_tls12_psk_to_ms_rfc4279_order(void)
premaster, (word32)sizeof(premaster),
(const byte*)"master secret", 13u,
seed, (word32)seed_len,
1, WC_HASH_TYPE_SHA256, NULL, INVALID_DEVID);
1, sha256_mac, NULL, INVALID_DEVID);
if (ret != 0) {
printf("FAIL: wc_PRF_TLS(TLS12_PSK_TO_MS reference) (%d)\n", ret);
return TEST_FAIL;
Expand Down Expand Up @@ -7905,7 +7905,7 @@ static int test_kdf_tls12_psk_to_ms_plain_psk_optional_other_secret(void)
premaster, (word32)sizeof(premaster),
(const byte*)"master secret", 13u,
seed, (word32)seed_len,
1, WC_HASH_TYPE_SHA256, NULL, INVALID_DEVID);
1, sha256_mac, NULL, INVALID_DEVID);
if (ret != 0) {
printf("FAIL: wc_PRF_TLS(TLS12_PSK_TO_MS plain PSK reference) (%d)\n", ret);
return TEST_FAIL;
Expand Down Expand Up @@ -8671,6 +8671,72 @@ static int test_hkdf_extract_truncated_output(void)
return TEST_OK;
}

static int test_tls12_prf(void)
{
/* PSA_ALG_TLS12_PRF output must match a direct wc_PRF_TLS reference using
* the correct MAC-algorithm id (sha256_mac). Regression for passing a
* WC_HASH_TYPE_* value to wc_PRF_TLS: WC_HASH_TYPE_SHA256 aliases
* sha512_mac, so the PRF returned HASH_TYPE_E on SHA-512-less builds and
* the wrong digest otherwise. */
#if !defined(WOLFSSL_HAVE_PRF) || defined(NO_HMAC) || defined(NO_SHA256)
return TEST_SKIPPED;
#else
static const uint8_t secret[] = "tls12 prf secret material";
static const uint8_t label[] = "test label";
static const uint8_t seed[] = "prf test seed bytes";
uint8_t ref[40];
uint8_t out[40];
psa_key_derivation_operation_t op;
psa_status_t st;
int ret;

ret = wc_PRF_TLS(ref, (word32)sizeof(ref),
secret, (word32)(sizeof(secret) - 1u),
label, (word32)(sizeof(label) - 1u),
seed, (word32)(sizeof(seed) - 1u),
1, sha256_mac, NULL, INVALID_DEVID);
if (ret != 0) {
printf("FAIL: wc_PRF_TLS(sha256_mac) reference (%d)\n", ret);
return TEST_FAIL;
}

memset(&op, 0, sizeof(op));
st = psa_key_derivation_setup(&op, PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256));
if (check_status(st, "setup(TLS12_PRF)") != TEST_OK)
return TEST_FAIL;
st = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_SECRET,
secret, sizeof(secret) - 1u);
if (check_status(st, "input secret(TLS12_PRF)") != TEST_OK) {
psa_key_derivation_abort(&op);
return TEST_FAIL;
}
st = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_LABEL,
label, sizeof(label) - 1u);
if (check_status(st, "input label(TLS12_PRF)") != TEST_OK) {
psa_key_derivation_abort(&op);
return TEST_FAIL;
}
st = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_SEED,
seed, sizeof(seed) - 1u);
if (check_status(st, "input seed(TLS12_PRF)") != TEST_OK) {
psa_key_derivation_abort(&op);
return TEST_FAIL;
}
st = psa_key_derivation_output_bytes(&op, out, sizeof(out));
if (check_status(st, "output(TLS12_PRF)") != TEST_OK) {
psa_key_derivation_abort(&op);
return TEST_FAIL;
}
(void)psa_key_derivation_abort(&op);

if (check_buf_eq("TLS12_PRF matches wc_PRF_TLS(sha256_mac)",
out, ref, sizeof(out)) != TEST_OK)
return TEST_FAIL;

return TEST_OK;
#endif
}

int main(int argc, char** argv)
{
psa_status_t st;
Expand Down Expand Up @@ -9303,6 +9369,11 @@ int main(int argc, char** argv)
return TEST_FAIL;
}
}
if (only == NULL || strcmp(only, "tls12_prf") == 0) {
if (run_named_test("tls12_prf", test_tls12_prf) == TEST_FAIL) {
return TEST_FAIL;
}
}

printf("PSA API test: OK (passed=%d skipped=%d)\n",
tests_passed, tests_skipped);
Expand Down
Loading