Skip to content

Commit 4cb9dde

Browse files
New function psa_copy_key
Copy a key from one slot to another. Implemented and smoke-tested.
1 parent 0ce26e3 commit 4cb9dde

File tree

4 files changed

+412
-129
lines changed

4 files changed

+412
-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
*/
@@ -545,139 +679,70 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle,
545679
size_t data_size,
546680
size_t *data_length);
547681

548-
/**@}*/
549-
550-
/** \defgroup policy Key policies
551-
* @{
552-
*/
553-
554-
/** The type of the key policy data structure.
555-
*
556-
* Before calling any function on a key policy, the application must initialize
557-
* it by any of the following means:
558-
* - Set the structure to all-bits-zero, for example:
559-
* \code
560-
* psa_key_policy_t policy;
561-
* memset(&policy, 0, sizeof(policy));
562-
* \endcode
563-
* - Initialize the structure to logical zero values, for example:
564-
* \code
565-
* psa_key_policy_t policy = {0};
566-
* \endcode
567-
* - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT,
568-
* for example:
569-
* \code
570-
* psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
571-
* \endcode
572-
* - Assign the result of the function psa_key_policy_init()
573-
* to the structure, for example:
574-
* \code
575-
* psa_key_policy_t policy;
576-
* policy = psa_key_policy_init();
577-
* \endcode
578-
*
579-
* This is an implementation-defined \c struct. Applications should not
580-
* make any assumptions about the content of this structure except
581-
* as directed by the documentation of a specific implementation. */
582-
typedef struct psa_key_policy_s psa_key_policy_t;
583-
584-
/** \def PSA_KEY_POLICY_INIT
585-
*
586-
* This macro returns a suitable initializer for a key policy object of type
587-
* #psa_key_policy_t.
588-
*/
589-
#ifdef __DOXYGEN_ONLY__
590-
/* This is an example definition for documentation purposes.
591-
* Implementations should define a suitable value in `crypto_struct.h`.
592-
*/
593-
#define PSA_KEY_POLICY_INIT {0}
594-
#endif
595-
596-
/** Return an initial value for a key policy that forbids all usage of the key.
597-
*/
598-
static psa_key_policy_t psa_key_policy_init(void);
599-
600-
/** \brief Set the standard fields of a policy structure.
601-
*
602-
* Note that this function does not make any consistency check of the
603-
* parameters. The values are only checked when applying the policy to
604-
* a key slot with psa_set_key_policy().
605-
*
606-
* \param[in,out] policy The key policy to modify. It must have been
607-
* initialized as per the documentation for
608-
* #psa_key_policy_t.
609-
* \param usage The permitted uses for the key.
610-
* \param alg The algorithm that the key may be used for.
611-
*/
612-
void psa_key_policy_set_usage(psa_key_policy_t *policy,
613-
psa_key_usage_t usage,
614-
psa_algorithm_t alg);
615-
616-
/** \brief Retrieve the usage field of a policy structure.
617-
*
618-
* \param[in] policy The policy object to query.
619-
*
620-
* \return The permitted uses for a key with this policy.
621-
*/
622-
psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
623-
624-
/** \brief Retrieve the algorithm field of a policy structure.
625-
*
626-
* \param[in] policy The policy object to query.
627-
*
628-
* \return The permitted algorithm for a key with this policy.
629-
*/
630-
psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
631-
632-
/** \brief Set the usage policy on a key slot.
633-
*
634-
* This function must be called on an empty key slot, before importing,
635-
* generating or creating a key in the slot. Changing the policy of an
636-
* existing key is not permitted.
637-
*
638-
* Implementations may set restrictions on supported key policies
639-
* depending on the key type and the key slot.
640-
*
641-
* \param handle Handle to the key whose policy is to be changed.
642-
* \param[in] policy The policy object to query.
682+
/** Make a copy of a key.
683+
*
684+
* Copy key material from one location to another.
685+
*
686+
* This function is primarily useful to copy a key from one lifetime
687+
* to another. The target key retains its lifetime and location.
688+
*
689+
* In an implementation where slots have different ownerships,
690+
* this functin may be used to share a key with a different party,
691+
* subject to implementation-defined restrictions on key sharing.
692+
* In this case \p constraint would typically prevent the recipient
693+
* from exporting the key.
694+
*
695+
* The resulting key may only be used in a way that conforms to all
696+
* three of: the policy of the source key, the policy previously set
697+
* on the target, and the \p constraint parameter passed when calling
698+
* this function.
699+
* - The usage flags on the resulting key are the bitwise-and of the
700+
* usage flags on the source policy, the previously-set target policy
701+
* and the policy constraint.
702+
* - If all three policies allow the same algorithm or wildcard-based
703+
* algorithm policy, the resulting key has the same algorithm policy.
704+
* - If one of the policies allows an algorithm and all the other policies
705+
* either allow the same algorithm or a wildcard-based algorithm policy
706+
* that includes this algorithm, the resulting key allows the same
707+
* algorithm.
708+
*
709+
* The effect of this function on implementation-defined metadata is
710+
* implementation-defined.
711+
*
712+
* \param source_handle The key to copy. It must be a handle to an
713+
* occupied slot.
714+
* \param target_handle A handle to the target slot. It must not contain
715+
* key material yet.
716+
* \param[in] constraint An optional policy constraint. If this parameter
717+
* is non-null then the resulting key will conform
718+
* to this policy in addition to the source policy
719+
* and the policy already present on the target
720+
* slot. If this parameter is null then the
721+
* function behaves in the same way as if it was
722+
* the target policy, i.e. only the source and
723+
* target policies apply.
643724
*
644725
* \retval #PSA_SUCCESS
645-
* Success.
646-
* If the key is persistent, it is implementation-defined whether
647-
* the policy has been saved to persistent storage. Implementations
648-
* may defer saving the policy until the key material is created.
649726
* \retval #PSA_ERROR_INVALID_HANDLE
650727
* \retval #PSA_ERROR_OCCUPIED_SLOT
651-
* \retval #PSA_ERROR_NOT_SUPPORTED
728+
* \p target already contains key material.
729+
* \retval #PSA_ERROR_EMPTY_SLOT
730+
* \p source does not contain key material.
652731
* \retval #PSA_ERROR_INVALID_ARGUMENT
732+
* The policy constraints on the source, on the target and
733+
* \p constraints are incompatible.
734+
* \retval #PSA_ERROR_NOT_PERMITTED
735+
* The source key is not exportable and its lifetime does not
736+
* allow copying it to the target's lifetime.
737+
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
738+
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
653739
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
654740
* \retval #PSA_ERROR_HARDWARE_FAILURE
655741
* \retval #PSA_ERROR_TAMPERING_DETECTED
656-
* \retval #PSA_ERROR_BAD_STATE
657-
* The library has not been previously initialized by psa_crypto_init().
658-
* It is implementation-dependent whether a failure to initialize
659-
* results in this error code.
660-
*/
661-
psa_status_t psa_set_key_policy(psa_key_handle_t handle,
662-
const psa_key_policy_t *policy);
663-
664-
/** \brief Get the usage policy for a key slot.
665-
*
666-
* \param handle Handle to the key slot whose policy is being queried.
667-
* \param[out] policy On success, the key's policy.
668-
*
669-
* \retval #PSA_SUCCESS
670-
* \retval #PSA_ERROR_INVALID_HANDLE
671-
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
672-
* \retval #PSA_ERROR_HARDWARE_FAILURE
673-
* \retval #PSA_ERROR_TAMPERING_DETECTED
674-
* \retval #PSA_ERROR_BAD_STATE
675-
* The library has not been previously initialized by psa_crypto_init().
676-
* It is implementation-dependent whether a failure to initialize
677-
* results in this error code.
678742
*/
679-
psa_status_t psa_get_key_policy(psa_key_handle_t handle,
680-
psa_key_policy_t *policy);
743+
psa_status_t psa_copy_key(psa_key_handle_t source_handle,
744+
psa_key_handle_t target_handle,
745+
const psa_key_policy_t *constraint);
681746

682747
/**@}*/
683748

0 commit comments

Comments
 (0)