Skip to content

Commit ea2e360

Browse files
Merge branch 'psa-copy_key' into psa-api-1.0-beta
New function psa_copy_key(). Conflicts: * library/psa_crypto.c: trivial conflicts due to consecutive changes. * tests/suites/test_suite_psa_crypto.data: the same code was added on both sides, but with a conflict resolution on one side. * tests/suites/test_suite_psa_crypto_metadata.function: the same code was added on both sides, but with a conflict resolution on one side.
2 parents b865df0 + 4cb9dde commit ea2e360

File tree

5 files changed

+430
-129
lines changed

5 files changed

+430
-129
lines changed

include/psa/crypto.h

Lines changed: 189 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,140 @@ psa_status_t psa_crypto_init(void);
9393

9494
/**@}*/
9595

96+
/** \defgroup policy Key policies
97+
* @{
98+
*/
99+
100+
/** The type of the key policy data structure.
101+
*
102+
* Before calling any function on a key policy, the application must initialize
103+
* it by any of the following means:
104+
* - Set the structure to all-bits-zero, for example:
105+
* \code
106+
* psa_key_policy_t policy;
107+
* memset(&policy, 0, sizeof(policy));
108+
* \endcode
109+
* - Initialize the structure to logical zero values, for example:
110+
* \code
111+
* psa_key_policy_t policy = {0};
112+
* \endcode
113+
* - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT,
114+
* for example:
115+
* \code
116+
* psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
117+
* \endcode
118+
* - Assign the result of the function psa_key_policy_init()
119+
* to the structure, for example:
120+
* \code
121+
* psa_key_policy_t policy;
122+
* policy = psa_key_policy_init();
123+
* \endcode
124+
*
125+
* This is an implementation-defined \c struct. Applications should not
126+
* make any assumptions about the content of this structure except
127+
* as directed by the documentation of a specific implementation. */
128+
typedef struct psa_key_policy_s psa_key_policy_t;
129+
130+
/** \def PSA_KEY_POLICY_INIT
131+
*
132+
* This macro returns a suitable initializer for a key policy object of type
133+
* #psa_key_policy_t.
134+
*/
135+
#ifdef __DOXYGEN_ONLY__
136+
/* This is an example definition for documentation purposes.
137+
* Implementations should define a suitable value in `crypto_struct.h`.
138+
*/
139+
#define PSA_KEY_POLICY_INIT {0}
140+
#endif
141+
142+
/** Return an initial value for a key policy that forbids all usage of the key.
143+
*/
144+
static psa_key_policy_t psa_key_policy_init(void);
145+
146+
/** \brief Set the standard fields of a policy structure.
147+
*
148+
* Note that this function does not make any consistency check of the
149+
* parameters. The values are only checked when applying the policy to
150+
* a key slot with psa_set_key_policy().
151+
*
152+
* \param[in,out] policy The key policy to modify. It must have been
153+
* initialized as per the documentation for
154+
* #psa_key_policy_t.
155+
* \param usage The permitted uses for the key.
156+
* \param alg The algorithm that the key may be used for.
157+
*/
158+
void psa_key_policy_set_usage(psa_key_policy_t *policy,
159+
psa_key_usage_t usage,
160+
psa_algorithm_t alg);
161+
162+
/** \brief Retrieve the usage field of a policy structure.
163+
*
164+
* \param[in] policy The policy object to query.
165+
*
166+
* \return The permitted uses for a key with this policy.
167+
*/
168+
psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
169+
170+
/** \brief Retrieve the algorithm field of a policy structure.
171+
*
172+
* \param[in] policy The policy object to query.
173+
*
174+
* \return The permitted algorithm for a key with this policy.
175+
*/
176+
psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
177+
178+
/** \brief Set the usage policy on a key slot.
179+
*
180+
* This function must be called on an empty key slot, before importing,
181+
* generating or creating a key in the slot. Changing the policy of an
182+
* existing key is not permitted.
183+
*
184+
* Implementations may set restrictions on supported key policies
185+
* depending on the key type and the key slot.
186+
*
187+
* \param handle Handle to the key whose policy is to be changed.
188+
* \param[in] policy The policy object to query.
189+
*
190+
* \retval #PSA_SUCCESS
191+
* Success.
192+
* If the key is persistent, it is implementation-defined whether
193+
* the policy has been saved to persistent storage. Implementations
194+
* may defer saving the policy until the key material is created.
195+
* \retval #PSA_ERROR_INVALID_HANDLE
196+
* \retval #PSA_ERROR_OCCUPIED_SLOT
197+
* \retval #PSA_ERROR_NOT_SUPPORTED
198+
* \retval #PSA_ERROR_INVALID_ARGUMENT
199+
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
200+
* \retval #PSA_ERROR_HARDWARE_FAILURE
201+
* \retval #PSA_ERROR_TAMPERING_DETECTED
202+
* \retval #PSA_ERROR_BAD_STATE
203+
* The library has not been previously initialized by psa_crypto_init().
204+
* It is implementation-dependent whether a failure to initialize
205+
* results in this error code.
206+
*/
207+
psa_status_t psa_set_key_policy(psa_key_handle_t handle,
208+
const psa_key_policy_t *policy);
209+
210+
/** \brief Get the usage policy for a key slot.
211+
*
212+
* \param handle Handle to the key slot whose policy is being queried.
213+
* \param[out] policy On success, the key's policy.
214+
*
215+
* \retval #PSA_SUCCESS
216+
* \retval #PSA_ERROR_INVALID_HANDLE
217+
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
218+
* \retval #PSA_ERROR_HARDWARE_FAILURE
219+
* \retval #PSA_ERROR_TAMPERING_DETECTED
220+
* \retval #PSA_ERROR_BAD_STATE
221+
* The library has not been previously initialized by psa_crypto_init().
222+
* It is implementation-dependent whether a failure to initialize
223+
* results in this error code.
224+
*/
225+
psa_status_t psa_get_key_policy(psa_key_handle_t handle,
226+
psa_key_policy_t *policy);
227+
228+
/**@}*/
229+
96230
/** \defgroup key_management Key management
97231
* @{
98232
*/
@@ -612,139 +746,70 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle,
612746
size_t data_size,
613747
size_t *data_length);
614748

615-
/**@}*/
616-
617-
/** \defgroup policy Key policies
618-
* @{
619-
*/
620-
621-
/** The type of the key policy data structure.
622-
*
623-
* Before calling any function on a key policy, the application must initialize
624-
* it by any of the following means:
625-
* - Set the structure to all-bits-zero, for example:
626-
* \code
627-
* psa_key_policy_t policy;
628-
* memset(&policy, 0, sizeof(policy));
629-
* \endcode
630-
* - Initialize the structure to logical zero values, for example:
631-
* \code
632-
* psa_key_policy_t policy = {0};
633-
* \endcode
634-
* - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT,
635-
* for example:
636-
* \code
637-
* psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
638-
* \endcode
639-
* - Assign the result of the function psa_key_policy_init()
640-
* to the structure, for example:
641-
* \code
642-
* psa_key_policy_t policy;
643-
* policy = psa_key_policy_init();
644-
* \endcode
645-
*
646-
* This is an implementation-defined \c struct. Applications should not
647-
* make any assumptions about the content of this structure except
648-
* as directed by the documentation of a specific implementation. */
649-
typedef struct psa_key_policy_s psa_key_policy_t;
650-
651-
/** \def PSA_KEY_POLICY_INIT
652-
*
653-
* This macro returns a suitable initializer for a key policy object of type
654-
* #psa_key_policy_t.
655-
*/
656-
#ifdef __DOXYGEN_ONLY__
657-
/* This is an example definition for documentation purposes.
658-
* Implementations should define a suitable value in `crypto_struct.h`.
659-
*/
660-
#define PSA_KEY_POLICY_INIT {0}
661-
#endif
662-
663-
/** Return an initial value for a key policy that forbids all usage of the key.
664-
*/
665-
static psa_key_policy_t psa_key_policy_init(void);
666-
667-
/** \brief Set the standard fields of a policy structure.
668-
*
669-
* Note that this function does not make any consistency check of the
670-
* parameters. The values are only checked when applying the policy to
671-
* a key slot with psa_set_key_policy().
672-
*
673-
* \param[in,out] policy The key policy to modify. It must have been
674-
* initialized as per the documentation for
675-
* #psa_key_policy_t.
676-
* \param usage The permitted uses for the key.
677-
* \param alg The algorithm that the key may be used for.
678-
*/
679-
void psa_key_policy_set_usage(psa_key_policy_t *policy,
680-
psa_key_usage_t usage,
681-
psa_algorithm_t alg);
682-
683-
/** \brief Retrieve the usage field of a policy structure.
684-
*
685-
* \param[in] policy The policy object to query.
686-
*
687-
* \return The permitted uses for a key with this policy.
688-
*/
689-
psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
690-
691-
/** \brief Retrieve the algorithm field of a policy structure.
692-
*
693-
* \param[in] policy The policy object to query.
694-
*
695-
* \return The permitted algorithm for a key with this policy.
696-
*/
697-
psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
698-
699-
/** \brief Set the usage policy on a key slot.
700-
*
701-
* This function must be called on an empty key slot, before importing,
702-
* generating or creating a key in the slot. Changing the policy of an
703-
* existing key is not permitted.
704-
*
705-
* Implementations may set restrictions on supported key policies
706-
* depending on the key type and the key slot.
707-
*
708-
* \param handle Handle to the key whose policy is to be changed.
709-
* \param[in] policy The policy object to query.
749+
/** Make a copy of a key.
750+
*
751+
* Copy key material from one location to another.
752+
*
753+
* This function is primarily useful to copy a key from one lifetime
754+
* to another. The target key retains its lifetime and location.
755+
*
756+
* In an implementation where slots have different ownerships,
757+
* this functin may be used to share a key with a different party,
758+
* subject to implementation-defined restrictions on key sharing.
759+
* In this case \p constraint would typically prevent the recipient
760+
* from exporting the key.
761+
*
762+
* The resulting key may only be used in a way that conforms to all
763+
* three of: the policy of the source key, the policy previously set
764+
* on the target, and the \p constraint parameter passed when calling
765+
* this function.
766+
* - The usage flags on the resulting key are the bitwise-and of the
767+
* usage flags on the source policy, the previously-set target policy
768+
* and the policy constraint.
769+
* - If all three policies allow the same algorithm or wildcard-based
770+
* algorithm policy, the resulting key has the same algorithm policy.
771+
* - If one of the policies allows an algorithm and all the other policies
772+
* either allow the same algorithm or a wildcard-based algorithm policy
773+
* that includes this algorithm, the resulting key allows the same
774+
* algorithm.
775+
*
776+
* The effect of this function on implementation-defined metadata is
777+
* implementation-defined.
778+
*
779+
* \param source_handle The key to copy. It must be a handle to an
780+
* occupied slot.
781+
* \param target_handle A handle to the target slot. It must not contain
782+
* key material yet.
783+
* \param[in] constraint An optional policy constraint. If this parameter
784+
* is non-null then the resulting key will conform
785+
* to this policy in addition to the source policy
786+
* and the policy already present on the target
787+
* slot. If this parameter is null then the
788+
* function behaves in the same way as if it was
789+
* the target policy, i.e. only the source and
790+
* target policies apply.
710791
*
711792
* \retval #PSA_SUCCESS
712-
* Success.
713-
* If the key is persistent, it is implementation-defined whether
714-
* the policy has been saved to persistent storage. Implementations
715-
* may defer saving the policy until the key material is created.
716793
* \retval #PSA_ERROR_INVALID_HANDLE
717794
* \retval #PSA_ERROR_OCCUPIED_SLOT
718-
* \retval #PSA_ERROR_NOT_SUPPORTED
795+
* \p target already contains key material.
796+
* \retval #PSA_ERROR_EMPTY_SLOT
797+
* \p source does not contain key material.
719798
* \retval #PSA_ERROR_INVALID_ARGUMENT
799+
* The policy constraints on the source, on the target and
800+
* \p constraints are incompatible.
801+
* \retval #PSA_ERROR_NOT_PERMITTED
802+
* The source key is not exportable and its lifetime does not
803+
* allow copying it to the target's lifetime.
804+
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
805+
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
720806
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
721807
* \retval #PSA_ERROR_HARDWARE_FAILURE
722808
* \retval #PSA_ERROR_TAMPERING_DETECTED
723-
* \retval #PSA_ERROR_BAD_STATE
724-
* The library has not been previously initialized by psa_crypto_init().
725-
* It is implementation-dependent whether a failure to initialize
726-
* results in this error code.
727-
*/
728-
psa_status_t psa_set_key_policy(psa_key_handle_t handle,
729-
const psa_key_policy_t *policy);
730-
731-
/** \brief Get the usage policy for a key slot.
732-
*
733-
* \param handle Handle to the key slot whose policy is being queried.
734-
* \param[out] policy On success, the key's policy.
735-
*
736-
* \retval #PSA_SUCCESS
737-
* \retval #PSA_ERROR_INVALID_HANDLE
738-
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
739-
* \retval #PSA_ERROR_HARDWARE_FAILURE
740-
* \retval #PSA_ERROR_TAMPERING_DETECTED
741-
* \retval #PSA_ERROR_BAD_STATE
742-
* The library has not been previously initialized by psa_crypto_init().
743-
* It is implementation-dependent whether a failure to initialize
744-
* results in this error code.
745809
*/
746-
psa_status_t psa_get_key_policy(psa_key_handle_t handle,
747-
psa_key_policy_t *policy);
810+
psa_status_t psa_copy_key(psa_key_handle_t source_handle,
811+
psa_key_handle_t target_handle,
812+
const psa_key_policy_t *constraint);
748813

749814
/**@}*/
750815

include/psa/crypto_values.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,24 @@
14041404
PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \
14051405
(alg) == PSA_ALG_ANY_HASH)
14061406

1407+
/** Whether the specified algorithm encoding is a wildcard.
1408+
*
1409+
* Wildcard values may only be used to set the usage algorithm field in
1410+
* a policy, not to perform an operation.
1411+
*
1412+
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
1413+
*
1414+
* \return 1 if \c alg is a wildcard algorithm encoding.
1415+
* \return 0 if \c alg is a non-wildcard algorithm encoding (suitable for
1416+
* an operation).
1417+
* \return This macro may return either 0 or 1 if \c alg is not a supported
1418+
* algorithm identifier.
1419+
*/
1420+
#define PSA_ALG_IS_WILDCARD(alg) \
1421+
(PSA_ALG_IS_HASH_AND_SIGN(alg) ? \
1422+
PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \
1423+
(alg) == PSA_ALG_ANY_HASH)
1424+
14071425
/**@}*/
14081426

14091427
/** \defgroup key_lifetimes Key lifetimes

0 commit comments

Comments
 (0)