66 *
77 * Workmem layout for the sign task:
88 * 1. Hash digest of the message to be signed (size: digestsz).
9+ *
10+ * Workmem layout for the sign digest task:
11+ * 1. Hash digest of the message to be signed (size: digestsz).
12+ * 2. Output of the rndinrange subtask (size: curve_op_size, which is the
13+ * max size in bytes of parameters and operands for the selected curve).
14+ *
915 * Other IK tasks don't need workmem memory.
1016 */
1117
18+ #include <string.h>
1219#include <silexpk/core.h>
1320#include <silexpk/iomem.h>
1421#include <sxsymcrypt/hash.h>
@@ -90,15 +97,15 @@ static int exit_ikg(struct sitask *t)
9097 return SX_ERR_HW_PROCESSING ;
9198}
9299
93- static int start_ecdsa_ik_sign (struct sitask * t , struct siwq * wq );
100+ static int start_ecdsa_ik_sign_wq (struct sitask * t , struct siwq * wq );
94101
95102static int finish_ecdsa_ik_sign (struct sitask * t , struct siwq * wq )
96103{
97104 (void )wq ;
98105
99106 if ((t -> statuscode == SX_ERR_INVALID_SIGNATURE ) && (t -> params .ik .attempts -- )) {
100107 sx_pk_release_req (t -> pk );
101- si_wq_run_after (t , & t -> params .ik .wq , start_ecdsa_ik_sign );
108+ si_wq_run_after (t , & t -> params .ik .wq , start_ecdsa_ik_sign_wq );
102109 return (t -> statuscode = SX_OK );
103110 }
104111
@@ -114,17 +121,12 @@ static int finish_ecdsa_ik_sign(struct sitask *t, struct siwq *wq)
114121 return exit_ikg (t );
115122}
116123
117- static int start_ecdsa_ik_sign (struct sitask * t , struct siwq * wq )
124+ static int start_ecdsa_ik_sign (struct sitask * t )
118125{
119126 struct sx_pk_acq_req pkreq ;
120127 struct sx_pk_inops_ik_ecdsa_sign inputs ;
121128 int opsz ;
122- size_t digestsz = sx_hash_get_digestsz (& t -> u .h );
123- (void )wq ;
124-
125- if (t -> statuscode != SX_OK ) {
126- return t -> statuscode ;
127- }
129+ size_t digestsz = sx_hash_get_alg_digestsz (t -> params .ik .privkey -> hashalg );
128130
129131 t -> actions .status = si_silexpk_status ;
130132 t -> actions .wait = si_silexpk_wait ;
@@ -149,15 +151,47 @@ static int start_ecdsa_ik_sign(struct sitask *t, struct siwq *wq)
149151 return SX_ERR_HW_PROCESSING ;
150152}
151153
154+ static int start_ecdsa_ik_sign_wq (struct sitask * t , struct siwq * wq )
155+ {
156+ (void )wq ;
157+ if (t -> statuscode != SX_OK ) {
158+ return t -> statuscode ;
159+ }
160+ return start_ecdsa_ik_sign (t );
161+ }
162+
152163static void run_ecdsa_ik_hash (struct sitask * t )
153164{
154165 /* Override SX_ERR_HW_PROCESSING state pre-set by si_task_run()
155166 * to be able to start the hash
156167 */
157168 t -> statuscode = SX_ERR_READY ;
158169 si_task_produce (t , t -> workmem , sx_hash_get_digestsz (& t -> u .h ));
170+ si_wq_run_after (t , & t -> params .ik .wq , start_ecdsa_ik_sign_wq );
171+ }
159172
160- si_wq_run_after (t , & t -> params .ik .wq , start_ecdsa_ik_sign );
173+ static void run_ik_sign (struct sitask * t )
174+ {
175+ start_ecdsa_ik_sign (t );
176+ }
177+
178+ static void ik_sign_consume_digest (struct sitask * t , const char * data , size_t sz )
179+ {
180+ size_t digestsz = sx_hash_get_alg_digestsz (t -> params .ik .privkey -> hashalg );
181+
182+ if (sz < digestsz ) {
183+ si_task_mark_final (t , SX_ERR_INPUT_BUFFER_TOO_SMALL );
184+ return ;
185+ } else if (sz > digestsz ) {
186+ si_task_mark_final (t , SX_ERR_TOO_BIG );
187+ return ;
188+ }
189+
190+ /* Copy the message digest to workmem. */
191+ memcpy (t -> workmem , data , sz );
192+
193+ t -> actions .consume = NULL ;
194+ t -> actions .run = run_ik_sign ;
161195}
162196
163197static void create_sign (struct sitask * t , const struct si_sig_privkey * privkey ,
@@ -174,6 +208,25 @@ static void create_sign(struct sitask *t, const struct si_sig_privkey *privkey,
174208 t -> params .ik .signature = signature ;
175209}
176210
211+ static void create_sign_digest (struct sitask * t , const struct si_sig_privkey * privkey ,
212+ struct si_sig_signature * signature )
213+ {
214+ size_t digestsz = sx_hash_get_alg_digestsz (privkey -> hashalg );
215+ size_t opsz = (size_t )sx_pk_curve_opsize (privkey -> key .ref .curve );
216+ size_t workmem_requirement = digestsz + opsz ;
217+
218+ if (t -> workmemsz < workmem_requirement ) {
219+ si_task_mark_final (t , SX_ERR_WORKMEM_BUFFER_TOO_SMALL );
220+ return ;
221+ }
222+
223+ t -> actions = (struct siactions ){0 };
224+ t -> statuscode = SX_ERR_READY ;
225+ t -> actions .consume = ik_sign_consume_digest ;
226+ t -> params .ik .privkey = privkey ;
227+ t -> params .ik .signature = signature ;
228+ }
229+
177230static int finish_ik_pubkey (struct sitask * t , struct siwq * wq )
178231{
179232 (void )wq ;
@@ -228,6 +281,7 @@ static void create_pubkey(struct sitask *t, const struct si_sig_privkey *privkey
228281
229282static const struct si_sig_def si_sig_def_ik = {
230283 .sign = create_sign ,
284+ .sign_digest = create_sign_digest ,
231285 .pubkey = create_pubkey ,
232286};
233287
0 commit comments