Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf_security: Add Cracen key derivation for SPAKE2P keys #19744

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Vge0rge
Copy link
Contributor

@Vge0rge Vge0rge commented Jan 3, 2025

Adds support for key derivation of SPAKE2P keys with Cracen. It currently supports only SECP256R1 keys.

Ref: NCSDK-30368

@Vge0rge Vge0rge requested a review from a team as a code owner January 3, 2025 14:32
@github-actions github-actions bot added the changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. label Jan 3, 2025
@NordicBuilder
Copy link
Contributor

NordicBuilder commented Jan 3, 2025

CI Information

To view the history of this post, clich the 'edited' button above
Build number: 7

Inputs:

Sources:

sdk-nrf: PR head: 1ef07256aea087a7f665d8c13074309d8b8c408e

more details

sdk-nrf:

PR head: 1ef07256aea087a7f665d8c13074309d8b8c408e
merge base: ca3e7af8fee049a2b5543cc35a0869546a709d53
target head (main): 7ab99c837804a65140f23f3960c1cfff1f523ef2
Diff

Github labels

Enabled Name Description
ci-disabled Disable the ci execution
ci-all-test Run all of ci, no test spec filtering will be done
ci-force-downstream Force execution of downstream even if twister fails
ci-run-twister Force run twister
ci-run-zephyr-twister Force run zephyr twister
List of changed files detected by CI (5)
subsys
│  ├── nrf_security
│  │  ├── src
│  │  │  ├── drivers
│  │  │  │  ├── cracen
│  │  │  │  │  ├── cracenpsa
│  │  │  │  │  │  ├── include
│  │  │  │  │  │  │  │ cracen_psa.h
│  │  │  │  │  │  ├── src
│  │  │  │  │  │  │  ├── common.c
│  │  │  │  │  │  │  ├── common.h
│  │  │  │  │  │  │  │ key_management.c
│  │  │  │ psa_crypto_driver_wrappers.c

Outputs:

Toolchain

Version: 4cff34261a
Build docker image: docker-dtr.nordicsemi.no/sw-production/ncs-build:4cff34261a_bece0367df

Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped; ⚠️ Quarantine

  • ◻️ Toolchain - Skipped: existing toolchain is used
  • ❌ Build twister
    • sdk-nrf test count: 1710
  • ❌ Integration tests
    • ❌ test-fw-nrfconnect-chip
    • ❌ test-fw-nrfconnect-nrf-iot_cloud
    • ❌ test-fw-nrfconnect-nrf_crypto
    • ❌ test-fw-nrfconnect-tfm
    • ❌ test-sdk-find-my
    • ❌ test-sdk-sidewalk
    • ❌ test-sdk-dfu
Disabled integration tests
    • desktop52_verification
    • doc-internal
    • test_ble_nrf_config
    • test-fw-nrfconnect-apps
    • test-fw-nrfconnect-ble_mesh
    • test-fw-nrfconnect-ble_samples
    • test-fw-nrfconnect-boot
    • test-fw-nrfconnect-fem
    • test-fw-nrfconnect-nfc
    • test-fw-nrfconnect-nrf-iot_lwm2m
    • test-fw-nrfconnect-nrf-iot_mosh
    • test-fw-nrfconnect-nrf-iot_positioning
    • test-fw-nrfconnect-nrf-iot_samples
    • test-fw-nrfconnect-nrf-iot_serial_lte_modem
    • test-fw-nrfconnect-nrf-iot_thingy91
    • test-fw-nrfconnect-nrf-iot_zephyr_lwm2m
    • test-fw-nrfconnect-proprietary_esb
    • test-fw-nrfconnect-ps
    • test-fw-nrfconnect-rpc
    • test-fw-nrfconnect-rs
    • test-fw-nrfconnect-thread
    • test-fw-nrfconnect-zigbee
    • test-low-level
    • test-sdk-audio
    • test-sdk-mcuboot
    • test-sdk-pmic-samples
    • test-sdk-wifi
    • test-secdom-samples-public

Note: This message is automatically posted and updated by the CI

@Damian-Nordic
Copy link
Contributor

Damian-Nordic commented Jan 22, 2025

I tested this change and tried to generate Spake2+ verifier for the following parameters:

  • salt: 5350414b453250204b65792053616c74
  • iteration count: 1000
  • passcode: 20202021 (encoded as 32-bit little-endian integer)

The outcome should be:

b96170aae803346884724fe9a3b287c30330c2a660375d17bb205a8cf1aecb350457f8ab79ee253ab6a8e46bb09e543ae422736de501e3db37d441fe344920d09548e4c18240630c4ff4913c53513839b7c07fcc0627a1b8573a149fcd1fa466cf

I get this result on nRF52 + Oberon, but on nRF54L with this PR I get:

E: Verifier
E: 2c 01 00 00 a0 0f 00 20 |,...... 
E: f4 01 00 00 2c 01 00 00 |....,...
E: a0 0f 00 20 00 00 00 00 |... ....
E: 78 3a 00 20 08 3f 01 20 |x:. .?. 
E: 9d 3f 06 00 18 00 00 00 |.?......
E: 38 37 01 20 ff 00 00 00 |87. ....
E: 38 37 01 20 38 37 01 20 |87. 87. 
E: 57 26 06 00 00 00 00 00 |W&......
E: 20 ea 00 20 a0 e8 00 20 | .. ... 
E: 35 13 05 00 a0 e8 00 20 |5...... 
E: a4 7a 01 20 c1 fd 08 00 |.z. ....
E: a3 03 05 00 00 00 00 00 |........
E: 00                      |.       
E: Exited with code 0

EDIT: Ah, I forgot to check the return value from psa_export_public_key in my test. Thus, it seems exporting the SPAKE2P public key (verifier) is not yet implemented by this PR.

@Vge0rge
Copy link
Contributor Author

Vge0rge commented Jan 23, 2025

I tested this change and tried to generate Spake2+ verifier for the following parameters:

  • salt: 5350414b453250204b65792053616c74
  • iteration count: 1000
  • passcode: 20202021 (encoded as 32-bit little-endian integer)

The outcome should be:

b96170aae803346884724fe9a3b287c30330c2a660375d17bb205a8cf1aecb350457f8ab79ee253ab6a8e46bb09e543ae422736de501e3db37d441fe344920d09548e4c18240630c4ff4913c53513839b7c07fcc0627a1b8573a149fcd1fa466cf

I get this result on nRF52 + Oberon, but on nRF54L with this PR I get:

E: Verifier
E: 2c 01 00 00 a0 0f 00 20 |,...... 
E: f4 01 00 00 2c 01 00 00 |....,...
E: a0 0f 00 20 00 00 00 00 |... ....
E: 78 3a 00 20 08 3f 01 20 |x:. .?. 
E: 9d 3f 06 00 18 00 00 00 |.?......
E: 38 37 01 20 ff 00 00 00 |87. ....
E: 38 37 01 20 38 37 01 20 |87. 87. 
E: 57 26 06 00 00 00 00 00 |W&......
E: 20 ea 00 20 a0 e8 00 20 | .. ... 
E: 35 13 05 00 a0 e8 00 20 |5...... 
E: a4 7a 01 20 c1 fd 08 00 |.z. ....
E: a3 03 05 00 00 00 00 00 |........
E: 00                      |.       
E: Exited with code 0

EDIT: Ah, I forgot to check the return value from psa_export_public_key in my test. Thus, it seems exporting the SPAKE2P public key (verifier) is not yet implemented by this PR.

Thanks for the feedback! We have another task for the export_public_key function but it might make sense to just do it here for completeness. Did you check if the derive_key function gives you the correct result from this function?

@Vge0rge Vge0rge force-pushed the derive_pake_cracen branch from e925800 to 99fcf77 Compare February 3, 2025 13:12
Adds support for key derivation of SPAKE2P keys with Cracen.
It currently supports only SECP256R1 keys.

Ref: NCSDK-30368

Signed-off-by: Georgios Vasilakis <georgios.vasilakis@nordicsemi.no>
@Vge0rge Vge0rge force-pushed the derive_pake_cracen branch from 99fcf77 to 78004d0 Compare February 3, 2025 13:35
@@ -471,6 +471,59 @@ static psa_status_t import_spake2p_key(const psa_key_attributes_t *attributes, c
return PSA_SUCCESS;
}

static psa_status_t cracen_derive_spake2p_key(const psa_key_attributes_t *attributes, const uint8_t *input,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compliance

@degjorva
Copy link
Contributor

@Damian-Nordic We have added support for psa_export_public_key. Please test it when you have the time

@Damian-Nordic
Copy link
Contributor

@Damian-Nordic We have added support for psa_export_public_key. Please test it when you have the time

Hmm. Somehow it's not working but I'll debug it. What's strange is that I get no error despite of returning no output because of this if:


	psa_status = cracen_ecc_get_ecurve_from_psa(psa_curve, key_bits_attr, &sx_curve);
	if (psa_status != PSA_SUCCESS) {
		return PSA_SUCCESS;
	}

This doesn't look right, no? :)

Add support for export of SPAKE2P keys to Cracen.
It currently only supports SECP256R1 keys.

Signed-off-by: Dag Erik Gjørvad <dag.erik.gjorvad@nordicsemi.no>
@degjorva
Copy link
Contributor

@Damian-Nordic We have added support for psa_export_public_key. Please test it when you have the time

Hmm. Somehow it's not working but I'll debug it. What's strange is that I get no error despite of returning no output because of this if:


	psa_status = cracen_ecc_get_ecurve_from_psa(psa_curve, key_bits_attr, &sx_curve);
	if (psa_status != PSA_SUCCESS) {
		return PSA_SUCCESS;
	}

This doesn't look right, no? :)

Ahaha, no, that has been in there for quite a while it seems. Updated it. Found the issue that caused it to be supposed to throw an error to begin with. Please try it again when you have the chance

@Damian-Nordic
Copy link
Contributor

Ahaha, no, that has been in there for quite a while it seems. Updated it. Found the issue that caused it to be supposed to throw an error to begin with. Please try it again when you have the chance

I checked that the Spake2+ private key derivation works correctly but public key needs a bit more work.

You used generic export_ecc_public_key_from_keypair function which seems to treat Spake2+ private key as ECDSA private key and it produces 65B public key (a single ECC point).
Note that the Spake2+ private key consists of not one but two group exponents (w0 and w1) which gives 64B in total, and the public key consists of w0 and L (where L is g*w1), which gives 32+65B in total. Thus, I think if export_ecc_public_key_from_keypair can be used, it should be given only w1 part of the private key and w0 should be just prepended to the result.

But I can approve the PR if you would prefer to first merge the private key part :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants