Skip to content

Commit 6fd4ee2

Browse files
authored
Merge pull request #20 from gilles-peskine-arm/psa-copy_key
New function psa_copy_key
2 parents ae2f5f1 + c9516fb commit 6fd4ee2

File tree

6 files changed

+990
-131
lines changed

6 files changed

+990
-131
lines changed

include/psa/crypto.h

Lines changed: 190 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
*/
@@ -530,139 +664,71 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle,
530664
size_t data_size,
531665
size_t *data_length);
532666

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

667733
/**@}*/
668734

0 commit comments

Comments
 (0)