Skip to content

Commit d6dc284

Browse files
authored
Merge pull request #177 from athoelke/crypto-1.3-integrate-pake
Integrate the PAKE Extension into the Crypto API specification
2 parents ef8ae85 + 8424c52 commit d6dc284

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+547
-1287
lines changed

doc/crypto/api.db/psa/crypto.h

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ typedef uint8_t psa_key_persistence_t;
1717
typedef uint16_t psa_key_type_t;
1818
typedef uint32_t psa_key_usage_t;
1919
typedef /* implementation-defined type */ psa_mac_operation_t;
20+
typedef /* implementation-defined type */ psa_pake_cipher_suite_t;
21+
typedef uint8_t psa_pake_family_t;
22+
typedef /* implementation-defined type */ psa_pake_operation_t;
23+
typedef uint32_t psa_pake_primitive_t;
24+
typedef uint8_t psa_pake_primitive_type_t;
25+
typedef uint8_t psa_pake_role_t;
26+
typedef uint8_t psa_pake_step_t;
2027
#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \
2128
/* implementation-defined value */
2229
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \
@@ -92,11 +99,13 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
9299
#define PSA_ALG_IS_HKDF_EXPAND(alg) /* specification-defined value */
93100
#define PSA_ALG_IS_HKDF_EXTRACT(alg) /* specification-defined value */
94101
#define PSA_ALG_IS_HMAC(alg) /* specification-defined value */
102+
#define PSA_ALG_IS_JPAKE(alg) /* specification-defined value */
95103
#define PSA_ALG_IS_KEY_AGREEMENT(alg) /* specification-defined value */
96104
#define PSA_ALG_IS_KEY_DERIVATION(alg) /* specification-defined value */
97105
#define PSA_ALG_IS_KEY_DERIVATION_STRETCHING(alg) \
98106
/* specification-defined value */
99107
#define PSA_ALG_IS_MAC(alg) /* specification-defined value */
108+
#define PSA_ALG_IS_PAKE(alg) /* specification-defined value */
100109
#define PSA_ALG_IS_PBKDF2_HMAC(alg) /* specification-defined value */
101110
#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) /* specification-defined value */
102111
#define PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) \
@@ -111,12 +120,16 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
111120
#define PSA_ALG_IS_SIGN_MESSAGE(alg) /* specification-defined value */
112121
#define PSA_ALG_IS_SP800_108_COUNTER_HMAC(alg) \
113122
/* specification-defined value */
123+
#define PSA_ALG_IS_SPAKE2P(alg) /* specification-defined value */
124+
#define PSA_ALG_IS_SPAKE2P_CMAC(alg) /* specification-defined value */
125+
#define PSA_ALG_IS_SPAKE2P_HMAC(alg) /* specification-defined value */
114126
#define PSA_ALG_IS_STANDALONE_KEY_AGREEMENT(alg) \
115127
/* specification-defined value */
116128
#define PSA_ALG_IS_STREAM_CIPHER(alg) /* specification-defined value */
117129
#define PSA_ALG_IS_TLS12_PRF(alg) /* specification-defined value */
118130
#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg) /* specification-defined value */
119131
#define PSA_ALG_IS_WILDCARD(alg) /* specification-defined value */
132+
#define PSA_ALG_JPAKE(hash_alg) /* specification-defined value */
120133
#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \
121134
/* specification-defined value */
122135
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) /* specification-defined value */
@@ -152,6 +165,9 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
152165
#define PSA_ALG_SP800_108_COUNTER_CMAC ((psa_algorithm_t)0x08000800)
153166
#define PSA_ALG_SP800_108_COUNTER_HMAC(hash_alg) \
154167
/* specification-defined value */
168+
#define PSA_ALG_SPAKE2P_CMAC(hash_alg) /* specification-defined value */
169+
#define PSA_ALG_SPAKE2P_HMAC(hash_alg) /* specification-defined value */
170+
#define PSA_ALG_SPAKE2P_MATTER ((psa_algoirithm_t)0x0A000609)
155171
#define PSA_ALG_STREAM_CIPHER ((psa_algorithm_t)0x04800100)
156172
#define PSA_ALG_TLS12_ECJPAKE_TO_PMS ((psa_algorithm_t)0x08000609)
157173
#define PSA_ALG_TLS12_PRF(hash_alg) /* specification-defined value */
@@ -189,7 +205,7 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
189205
#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \
190206
/* implementation-defined value */
191207
#define PSA_CRYPTO_API_VERSION_MAJOR 1
192-
#define PSA_CRYPTO_API_VERSION_MINOR 2
208+
#define PSA_CRYPTO_API_VERSION_MINOR 3
193209
#define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03)
194210
#define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30)
195211
#define PSA_ECC_FAMILY_FRP ((psa_ecc_family_t) 0x33)
@@ -278,6 +294,11 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
278294
#define PSA_KEY_TYPE_IS_KEY_PAIR(type) /* specification-defined value */
279295
#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) /* specification-defined value */
280296
#define PSA_KEY_TYPE_IS_RSA(type) /* specification-defined value */
297+
#define PSA_KEY_TYPE_IS_SPAKE2P(type) /* specification-defined value */
298+
#define PSA_KEY_TYPE_IS_SPAKE2P_KEY_PAIR(type) \
299+
/* specification-defined value */
300+
#define PSA_KEY_TYPE_IS_SPAKE2P_PUBLIC_KEY(type) \
301+
/* specification-defined value */
281302
#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) /* specification-defined value */
282303
#define PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(type) \
283304
/* specification-defined value */
@@ -291,6 +312,10 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
291312
#define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t)0x7001)
292313
#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x4001)
293314
#define PSA_KEY_TYPE_SM4 ((psa_key_type_t)0x2405)
315+
#define PSA_KEY_TYPE_SPAKE2P_GET_FAMILY(type) /* specification-defined value */
316+
#define PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(curve) /* specification-defined value */
317+
#define PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(curve) \
318+
/* specification-defined value */
294319
#define PSA_KEY_TYPE_XCHACHA20 ((psa_key_type_t)0x2007)
295320
#define PSA_KEY_USAGE_CACHE ((psa_key_usage_t)0x00000004)
296321
#define PSA_KEY_USAGE_COPY ((psa_key_usage_t)0x00000002)
@@ -307,6 +332,35 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
307332
/* implementation-defined value */
308333
#define PSA_MAC_MAX_SIZE /* implementation-defined value */
309334
#define PSA_MAC_OPERATION_INIT /* implementation-defined value */
335+
#define PSA_PAKE_CIPHER_SUITE_INIT /* implementation-defined value */
336+
#define PSA_PAKE_CONFIRMED_KEY 0
337+
#define PSA_PAKE_INPUT_MAX_SIZE /* implementation-defined value */
338+
#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \
339+
/* implementation-defined value */
340+
#define PSA_PAKE_OPERATION_INIT /* implementation-defined value */
341+
#define PSA_PAKE_OUTPUT_MAX_SIZE /* implementation-defined value */
342+
#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \
343+
/* implementation-defined value */
344+
#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \
345+
/* specification-defined value */
346+
#define PSA_PAKE_PRIMITIVE_GET_BITS(pake_primitive) \
347+
/* specification-defined value */
348+
#define PSA_PAKE_PRIMITIVE_GET_FAMILY(pake_primitive) \
349+
/* specification-defined value */
350+
#define PSA_PAKE_PRIMITIVE_GET_TYPE(pake_primitive) \
351+
/* specification-defined value */
352+
#define PSA_PAKE_PRIMITIVE_TYPE_DH ((psa_pake_primitive_type_t)0x02)
353+
#define PSA_PAKE_PRIMITIVE_TYPE_ECC ((psa_pake_primitive_type_t)0x01)
354+
#define PSA_PAKE_ROLE_CLIENT ((psa_pake_role_t)0x11)
355+
#define PSA_PAKE_ROLE_FIRST ((psa_pake_role_t)0x01)
356+
#define PSA_PAKE_ROLE_NONE ((psa_pake_role_t)0x00)
357+
#define PSA_PAKE_ROLE_SECOND ((psa_pake_role_t)0x02)
358+
#define PSA_PAKE_ROLE_SERVER ((psa_pake_role_t)0x12)
359+
#define PSA_PAKE_STEP_CONFIRM ((psa_pake_step_t)0x04)
360+
#define PSA_PAKE_STEP_KEY_SHARE ((psa_pake_step_t)0x01)
361+
#define PSA_PAKE_STEP_ZK_PROOF ((psa_pake_step_t)0x03)
362+
#define PSA_PAKE_STEP_ZK_PUBLIC ((psa_pake_step_t)0x02)
363+
#define PSA_PAKE_UNCONFIRMED_KEY 1
310364
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \
311365
/* implementation-defined value */
312366
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \
@@ -570,6 +624,44 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t * operation,
570624
psa_status_t psa_mac_verify_setup(psa_mac_operation_t * operation,
571625
psa_key_id_t key,
572626
psa_algorithm_t alg);
627+
psa_status_t psa_pake_abort(psa_pake_operation_t * operation);
628+
psa_pake_cipher_suite_t psa_pake_cipher_suite_init(void);
629+
psa_algorithm_t psa_pake_cs_get_algorithm(const psa_pake_cipher_suite_t* cipher_suite);
630+
uint32_t psa_pake_cs_get_key_confirmation(const psa_pake_cipher_suite_t* cipher_suite);
631+
psa_pake_primitive_t psa_pake_cs_get_primitive(const psa_pake_cipher_suite_t* cipher_suite);
632+
void psa_pake_cs_set_algorithm(psa_pake_cipher_suite_t* cipher_suite,
633+
psa_algorithm_t alg);
634+
void psa_pake_cs_set_key_confirmation(psa_pake_cipher_suite_t* cipher_suite,
635+
uint32_t key_confirmation);
636+
void psa_pake_cs_set_primitive(psa_pake_cipher_suite_t* cipher_suite,
637+
psa_pake_primitive_t primitive);
638+
psa_status_t psa_pake_get_shared_key(psa_pake_operation_t *operation,
639+
const psa_key_attributes_t * attributes,
640+
psa_key_id_t * key);
641+
psa_status_t psa_pake_input(psa_pake_operation_t *operation,
642+
psa_pake_step_t step,
643+
const uint8_t *input,
644+
size_t input_length);
645+
psa_pake_operation_t psa_pake_operation_init(void);
646+
psa_status_t psa_pake_output(psa_pake_operation_t *operation,
647+
psa_pake_step_t step,
648+
uint8_t *output,
649+
size_t output_size,
650+
size_t *output_length);
651+
psa_status_t psa_pake_set_context(psa_pake_operation_t *operation,
652+
const uint8_t *context,
653+
size_t context_len);
654+
psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation,
655+
const uint8_t *peer_id,
656+
size_t peer_id_len);
657+
psa_status_t psa_pake_set_role(psa_pake_operation_t *operation,
658+
psa_pake_role_t role);
659+
psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
660+
const uint8_t *user_id,
661+
size_t user_id_len);
662+
psa_status_t psa_pake_setup(psa_pake_operation_t *operation,
663+
psa_key_id_t password_key,
664+
const psa_pake_cipher_suite_t *cipher_suite);
573665
psa_status_t psa_purge_key(psa_key_id_t key);
574666
psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
575667
psa_key_id_t private_key,

doc/crypto/api/keys/attributes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Managing key attributes
112112
#. Set the key policy with `psa_set_key_usage_flags()` and `psa_set_key_algorithm()`.
113113
#. Set the key type with `psa_set_key_type()`. Skip this step if copying an existing key with `psa_copy_key()`.
114114
#. When generating a random key with `psa_generate_key()` or deriving a key with `psa_key_derivation_output_key()`, set the desired key size with `psa_set_key_bits()`.
115-
#. Call a key creation function: `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()`, `psa_key_agreement()`, or `psa_copy_key()`. This function reads the attribute object, creates a key with these attributes, and outputs an identifier for the newly created key.
115+
#. Call a key creation function: `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`. This function reads the attribute object, creates a key with these attributes, and outputs an identifier for the newly created key.
116116
#. Optionally call `psa_reset_key_attributes()`, now that the attribute object is no longer needed. Currently this call is not required as the attributes defined in this specification do not require additional resources beyond the object itself.
117117

118118
A typical sequence to query a key's attributes is as follows:

doc/crypto/api/keys/ids.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.. SPDX-FileCopyrightText: Copyright 2018-2022 Arm Limited and/or its affiliates <[email protected]>
1+
.. SPDX-FileCopyrightText: Copyright 2018-2022, 2024 Arm Limited and/or its affiliates <[email protected]>
22
.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license
33
44
.. _key-identifiers:
@@ -92,7 +92,7 @@ Attribute accessors
9292

9393
If the attribute object currently declares the key as volatile, which is the default lifetime of an attribute object, this function sets the lifetime attribute to `PSA_KEY_LIFETIME_PERSISTENT`.
9494

95-
This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()` or `psa_copy_key()`.
95+
This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`.
9696

9797
.. admonition:: Implementation note
9898

doc/crypto/api/keys/lifetimes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ Attribute accessors
273273

274274
To make a key persistent, give it a persistent key identifier by using `psa_set_key_id()`. By default, a key that has a persistent identifier is stored in the default storage area identifier by `PSA_KEY_LIFETIME_PERSISTENT`. Call this function to choose a storage area, or to explicitly declare the key as volatile.
275275

276-
This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()`, `psa_key_agreement()`, or `psa_copy_key()`.
276+
This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`.
277277

278278
.. admonition:: Implementation note
279279

doc/crypto/api/keys/management.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ New keys can be created in the following ways:
1818
* `psa_generate_key()` creates a key from randomly generated data.
1919
* `psa_key_derivation_output_key()` creates a key from data generated by a pseudorandom derivation process. See :secref:`kdf`.
2020
* `psa_key_agreement()` creates a key from the shared secret result of a key agreement process. See :secref:`key-agreement`.
21+
* `psa_pake_get_shared_key()` creates a key from the shared secret result of a password-authenticated key exchange. See :secref:`pake`.
2122
* `psa_copy_key()` duplicates an existing key with a different lifetime or with a more restrictive usage policy.
2223

2324
When creating a key, the attributes for the new key are specified in a `psa_key_attributes_t` object. Each key creation function defines how it uses the attributes.
@@ -670,3 +671,36 @@ This section defines the format of the key data that an implementation is requir
670671
- :code:`PSA_KEY_TYPE_DH_PUBLIC_KEY(dh_family)` where ``dh_family`` designates any Diffie-Hellman family.
671672

672673
The key data is the representation of the public key :math:`y = g^x\!\mod p` as a big-endian byte string. The length of the byte string is the length of the base prime :math:`p` in bytes.
674+
675+
* - SPAKE2+ key pair
676+
- :code:`PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(ecc_family)` where ``ecc_family`` designates an elliptic curve family.
677+
678+
The key consists of the two values :math:`w0` and :math:`w1`, which result from the SPAKE2+ registration phase, see :secref:`spake2p-registration`.
679+
:math:`w0` and :math:`w1` are scalars in the same range as an elliptic curve private key from the group used as the SPAKE2+ primitive group.
680+
681+
For the |API|, the default format for a SPAKE2+ key pair is the concatenation of the formatted values for :math:`w0` and :math:`w1`, using the standard formats for elliptic curve keys used by the |API|.
682+
For example, for SPAKE2+ over P-256 (secp256r1), the output from :code:`psa_export_key()` would be the concatenation of:
683+
684+
* The P-256 private key :math:`w0`.
685+
This is a 32-byte big-endian encoding of the integer :math:`w0`.
686+
* The P-256 private key :math:`w1`.
687+
This is a 32-byte big-endian encoding of the integer :math:`w1`.
688+
689+
* - SPAKE2+ public key
690+
- :code:`PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(ecc_family)` where ``ecc_family`` designates an elliptic curve family.
691+
692+
The public key consists of the two values :math:`w0` and :math:`L`, which result from the SPAKE2+ registration phase, see :secref:`spake2p-registration`.
693+
:math:`w0` is a scalar in the same range as a elliptic curve private key from the group used as the SPAKE2+ primitive group.
694+
:math:`L` is a point on the curve, similar to a public key from the same group, corresponding to the :math:`w1` value in the key pair.
695+
696+
For the |API|, the default format for a SPAKE2+ public key is the concatenation of the formatted values for :math:`w0` and :math:`L`, using the standard formats for elliptic curve keys used by the |API|.
697+
For example, for SPAKE2+ over P-256 (secp256r1), the output from :code:`psa_export_public_key()` would be the concatenation of:
698+
699+
* The P-256 private key :math:`w0`.
700+
This is a 32-byte big-endian encoding of the integer :math:`w0`.
701+
* The P-256 public key :math:`L`.
702+
This is a 65-byte concatenation of:
703+
704+
- The byte ``0x04``.
705+
- The 32-byte big-endian encoding of the x-coordinate of :math:`L`.
706+
- The 32-byte big-endian encoding of the y-coordinate of :math:`L`.

0 commit comments

Comments
 (0)