Skip to content

Commit 46c8301

Browse files
committed
Implement locking around wolfProvider signature operations to facilitate multithreaded flows with multiple threads sharing an underlying key.
1 parent 01a48e3 commit 46c8301

7 files changed

Lines changed: 314 additions & 52 deletions

File tree

include/wolfprovider/alg_funcs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ int wp_rsa_up_ref(wp_Rsa* rsa);
182182
void wp_rsa_free(wp_Rsa* rsa);
183183
int wp_rsa_get_type(wp_Rsa* rsa);
184184
int wp_rsa_get_bits(wp_Rsa* rsa);
185+
int wp_rsa_lock(wp_Rsa* rsa);
186+
int wp_rsa_unlock(wp_Rsa* rsa);
185187
RsaKey* wp_rsa_get_key(wp_Rsa* rsa);
186188
void wp_rsa_get_pss_mds(wp_Rsa* rsa, char** mdName, char** mgfMdName);
187189
int wp_rsa_get_pss_salt_len(wp_Rsa* rsa);
@@ -199,13 +201,17 @@ ecc_key* wp_ecc_get_key(wp_Ecc* ecc);
199201
WC_RNG* wp_ecc_get_rng(wp_Ecc* ecc);
200202
int wp_ecc_get_size(wp_Ecc* ecc);
201203
int wp_ecc_check_usage(wp_Ecc* ecc);
204+
int wp_ecc_lock(wp_Ecc* ecc);
205+
int wp_ecc_unlock(wp_Ecc* ecc);
202206

203207
/* Internal ECX types and functions. */
204208
typedef struct wp_Ecx wp_Ecx;
205209

206210
int wp_ecx_up_ref(wp_Ecx* ecx);
207211
void wp_ecx_free(wp_Ecx* ecx);
208212
void* wp_ecx_get_key(wp_Ecx* ecx);
213+
int wp_ecx_lock(wp_Ecx* ecx);
214+
int wp_ecx_unlock(wp_Ecx* ecx);
209215

210216
/* Internal DH types and functions. */
211217
typedef struct wp_Dh wp_Dh;

src/wp_ecc_kmgmt.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,76 @@ int wp_ecc_get_size(wp_Ecc* ecc)
299299
return (ecc->bits + 7) / 8;
300300
}
301301

302+
/**
303+
* Lock the ECC key mutex.
304+
*
305+
* This function locks the mutex associated with the ECC key object.
306+
* Use wp_ecc_unlock() to unlock after operations are complete.
307+
*
308+
* @param [in] ecc ECC key object.
309+
* @return 1 on success.
310+
* @return 0 on failure or when single-threaded build.
311+
*/
312+
int wp_ecc_lock(wp_Ecc* ecc)
313+
{
314+
#ifndef WP_SINGLE_THREADED
315+
int ok = 1;
316+
int rc;
317+
318+
if (ecc == NULL) {
319+
ok = 0;
320+
}
321+
else {
322+
rc = wc_LockMutex(&ecc->mutex);
323+
if (rc < 0) {
324+
ok = 0;
325+
}
326+
}
327+
328+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
329+
return ok;
330+
#else
331+
(void)ecc;
332+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1);
333+
return 1;
334+
#endif
335+
}
336+
337+
/**
338+
* Unlock the ECC key mutex.
339+
*
340+
* This function unlocks the mutex associated with the ECC key object.
341+
* Should only be called after a successful wp_ecc_lock() call.
342+
*
343+
* @param [in] ecc ECC key object.
344+
* @return 1 on success.
345+
* @return 0 on failure or when single-threaded build.
346+
*/
347+
int wp_ecc_unlock(wp_Ecc* ecc)
348+
{
349+
#ifndef WP_SINGLE_THREADED
350+
int ok = 1;
351+
int rc;
352+
353+
if (ecc == NULL) {
354+
ok = 0;
355+
}
356+
else {
357+
rc = wc_UnLockMutex(&ecc->mutex);
358+
if (rc < 0) {
359+
ok = 0;
360+
}
361+
}
362+
363+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
364+
return ok;
365+
#else
366+
(void)ecc;
367+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1);
368+
return 1;
369+
#endif
370+
}
371+
302372
/**
303373
* Create a new ECC key object.
304374
*

src/wp_ecdsa_sig.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,21 @@ static int wp_ecdsa_sign(wp_EcdsaSigCtx *ctx, unsigned char *sig,
280280
sigSize = *sigLen;
281281
}
282282
len = (word32)sigSize;
283-
PRIVATE_KEY_UNLOCK();
284-
rc = wc_ecc_sign_hash(tbs, (word32)tbsLen, sig, &len,
285-
wp_ecc_get_rng(ctx->ecc), wp_ecc_get_key(ctx->ecc));
286-
PRIVATE_KEY_LOCK();
287-
if (rc != 0) {
283+
if (wp_ecc_lock(ctx->ecc) != 1) {
288284
ok = 0;
289285
}
290-
else {
291-
*sigLen = len;
286+
if (ok) {
287+
PRIVATE_KEY_UNLOCK();
288+
rc = wc_ecc_sign_hash(tbs, (word32)tbsLen, sig, &len,
289+
wp_ecc_get_rng(ctx->ecc), wp_ecc_get_key(ctx->ecc));
290+
PRIVATE_KEY_LOCK();
291+
wp_ecc_unlock(ctx->ecc);
292+
if (rc != 0) {
293+
ok = 0;
294+
}
295+
else {
296+
*sigLen = len;
297+
}
292298
}
293299
}
294300
}

src/wp_ecx_kmgmt.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,76 @@ void* wp_ecx_get_key(wp_Ecx* ecx)
243243
return (void*)&ecx->key;
244244
}
245245

246+
/**
247+
* Lock the ECX key mutex.
248+
*
249+
* This function locks the mutex associated with the ECX key object.
250+
* Use wp_ecx_unlock() to unlock after operations are complete.
251+
*
252+
* @param [in] ecx ECX key object.
253+
* @return 1 on success.
254+
* @return 0 on failure or when single-threaded build.
255+
*/
256+
int wp_ecx_lock(wp_Ecx* ecx)
257+
{
258+
#ifndef WP_SINGLE_THREADED
259+
int ok = 1;
260+
int rc;
261+
262+
if (ecx == NULL) {
263+
ok = 0;
264+
}
265+
else {
266+
rc = wc_LockMutex(&ecx->mutex);
267+
if (rc < 0) {
268+
ok = 0;
269+
}
270+
}
271+
272+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
273+
return ok;
274+
#else
275+
(void)ecx;
276+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1);
277+
return 1;
278+
#endif
279+
}
280+
281+
/**
282+
* Unlock the ECX key mutex.
283+
*
284+
* This function unlocks the mutex associated with the ECX key object.
285+
* Should only be called after a successful wp_ecx_lock() call.
286+
*
287+
* @param [in] ecx ECX key object.
288+
* @return 1 on success.
289+
* @return 0 on failure or when single-threaded build.
290+
*/
291+
int wp_ecx_unlock(wp_Ecx* ecx)
292+
{
293+
#ifndef WP_SINGLE_THREADED
294+
int ok = 1;
295+
int rc;
296+
297+
if (ecx == NULL) {
298+
ok = 0;
299+
}
300+
else {
301+
rc = wc_UnLockMutex(&ecx->mutex);
302+
if (rc < 0) {
303+
ok = 0;
304+
}
305+
}
306+
307+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
308+
return ok;
309+
#else
310+
(void)ecx;
311+
WOLFPROV_LEAVE(WP_LOG_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1);
312+
return 1;
313+
#endif
314+
}
315+
246316
/**
247317
* Create a new ECX key object. Base function.
248318
*

src/wp_ecx_sig.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -436,12 +436,18 @@ static int wp_ed25519_digest_sign(wp_EcxSigCtx *ctx, unsigned char *sig,
436436
}
437437
}
438438
if (ok) {
439-
rc = wc_ed25519_sign_msg(tbs, (word32)tbsLen, sig, &len, ed25519);
440-
if (rc != 0) {
439+
if (wp_ecx_lock(ctx->ecx) != 1) {
441440
ok = 0;
442441
}
443-
else {
444-
*sigLen = len;
442+
if (ok) {
443+
rc = wc_ed25519_sign_msg(tbs, (word32)tbsLen, sig, &len, ed25519);
444+
wp_ecx_unlock(ctx->ecx);
445+
if (rc != 0) {
446+
ok = 0;
447+
}
448+
else {
449+
*sigLen = len;
450+
}
445451
}
446452
}
447453
}
@@ -578,13 +584,19 @@ static int wp_ed448_digest_sign(wp_EcxSigCtx *ctx, unsigned char *sig,
578584
}
579585
}
580586
if (ok) {
581-
rc = wc_ed448_sign_msg(tbs, (word32)tbsLen, sig, &len,
582-
(ed448_key*)wp_ecx_get_key(ctx->ecx), NULL, 0);
583-
if (rc != 0) {
587+
if (wp_ecx_lock(ctx->ecx) != 1) {
584588
ok = 0;
585589
}
586-
else {
587-
*sigLen = len;
590+
if (ok) {
591+
rc = wc_ed448_sign_msg(tbs, (word32)tbsLen, sig, &len,
592+
(ed448_key*)wp_ecx_get_key(ctx->ecx), NULL, 0);
593+
wp_ecx_unlock(ctx->ecx);
594+
if (rc != 0) {
595+
ok = 0;
596+
}
597+
else {
598+
*sigLen = len;
599+
}
588600
}
589601
}
590602
}

src/wp_rsa_kmgmt.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,76 @@ int wp_rsa_get_bits(wp_Rsa* rsa)
330330
return rsa->bits;
331331
}
332332

333+
/**
334+
* Lock the RSA key mutex.
335+
*
336+
* This function locks the mutex associated with the RSA key object to ensure
337+
* thread-safe access to the key data.
338+
*
339+
* @param [in] rsa RSA key object.
340+
* @return 1 on success.
341+
* @return 0 on failure or when single-threaded build.
342+
*/
343+
int wp_rsa_lock(wp_Rsa* rsa)
344+
{
345+
#ifndef WP_SINGLE_THREADED
346+
int ok = 1;
347+
int rc;
348+
349+
if (rsa == NULL) {
350+
ok = 0;
351+
}
352+
else {
353+
rc = wc_LockMutex(&rsa->mutex);
354+
if (rc < 0) {
355+
ok = 0;
356+
}
357+
}
358+
359+
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
360+
return ok;
361+
#else
362+
(void)rsa;
363+
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1);
364+
return 1;
365+
#endif
366+
}
367+
368+
/**
369+
* Unlock the RSA key mutex.
370+
*
371+
* This function unlocks the mutex associated with the RSA key object.
372+
* Should only be called after a successful wp_rsa_lock() call.
373+
*
374+
* @param [in] rsa RSA key object.
375+
* @return 1 on success.
376+
* @return 0 on failure or when single-threaded build.
377+
*/
378+
int wp_rsa_unlock(wp_Rsa* rsa)
379+
{
380+
#ifndef WP_SINGLE_THREADED
381+
int ok = 1;
382+
int rc;
383+
384+
if (rsa == NULL) {
385+
ok = 0;
386+
}
387+
else {
388+
rc = wc_UnLockMutex(&rsa->mutex);
389+
if (rc < 0) {
390+
ok = 0;
391+
}
392+
}
393+
394+
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
395+
return ok;
396+
#else
397+
(void)rsa;
398+
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1);
399+
return 1;
400+
#endif
401+
}
402+
333403
/**
334404
* Check the RSA key size is valid.
335405
*

0 commit comments

Comments
 (0)