Skip to content

Commit 7a7557c

Browse files
Zeroing out nonce-related stack buffers in musig part
1 parent 11d4670 commit 7a7557c

File tree

2 files changed

+52
-20
lines changed

2 files changed

+52
-20
lines changed

src/handler/sign_psbt/musig_signing.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ bool produce_and_yield_pubnonce(dispatcher_context_t *dc,
269269
return false;
270270
}
271271

272+
bool ret = false;
272273
uint8_t rand_i_j[32];
273274
compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j);
274275

@@ -281,8 +282,7 @@ bool produce_and_yield_pubnonce(dispatcher_context_t *dc,
281282
&secnonce,
282283
&pubnonce)) {
283284
PRINTF("MuSig2 nonce generation failed\n");
284-
SEND_SW(dc, SW_BAD_STATE); // should never happen
285-
return false;
285+
goto cleanup;
286286
}
287287

288288
if (!yield_musig_pubnonce(dc,
@@ -293,6 +293,15 @@ bool produce_and_yield_pubnonce(dispatcher_context_t *dc,
293293
musig_per_input_info.agg_key_tweaked.compressed_pubkey,
294294
keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) {
295295
PRINTF("Failed yielding MuSig2 pubnonce\n");
296+
goto cleanup;
297+
}
298+
299+
ret = true;
300+
301+
cleanup:
302+
explicit_bzero(rand_i_j, sizeof(rand_i_j));
303+
explicit_bzero(&secnonce, sizeof(secnonce));
304+
if (!ret) {
296305
SEND_SW(dc, SW_BAD_STATE); // should never happen
297306
return false;
298307
}
@@ -413,6 +422,8 @@ bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t
413422
&secnonce,
414423
&pubnonce)) {
415424
PRINTF("MuSig2 nonce generation failed\n");
425+
explicit_bzero(rand_i_j, sizeof(rand_i_j));
426+
explicit_bzero(&secnonce, sizeof(secnonce));
416427
SEND_SW(dc, SW_BAD_STATE); // should never happen
417428
return false;
418429
}
@@ -464,6 +475,8 @@ bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t
464475
} while (false);
465476

466477
explicit_bzero(&private_key, sizeof(private_key));
478+
explicit_bzero(rand_i_j, sizeof(rand_i_j));
479+
explicit_bzero(&secnonce, sizeof(secnonce));
467480

468481
if (err) {
469482
PRINTF("Partial signature generation failed\n");

src/musig/musig.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -264,27 +264,32 @@ int musig_nonce_gen(const uint8_t *rand,
264264
uint8_t msg[] = {0x00};
265265

266266
musig_nonce_hash(rand, rand_len, pk, aggpk, 0, msg, 1, NULL, 0, secnonce->k_1);
267-
if (CX_OK != cx_math_modm_no_throw(secnonce->k_1, 32, secp256k1_n, 32)) return -1;
267+
if (CX_OK != cx_math_modm_no_throw(secnonce->k_1, 32, secp256k1_n, 32)) goto nonce_gen_fail;
268268
musig_nonce_hash(rand, rand_len, pk, aggpk, 1, msg, 1, NULL, 0, secnonce->k_2);
269-
if (CX_OK != cx_math_modm_no_throw(secnonce->k_2, 32, secp256k1_n, 32)) return -1;
269+
if (CX_OK != cx_math_modm_no_throw(secnonce->k_2, 32, secp256k1_n, 32)) goto nonce_gen_fail;
270270

271271
if (is_array_all_zeros(secnonce->k_1, sizeof(secnonce->k_1)) ||
272272
is_array_all_zeros(secnonce->k_2, sizeof(secnonce->k_2))) {
273273
// this can only happen with negligible probability
274-
return -1;
274+
goto nonce_gen_fail;
275275
}
276276

277277
memcpy(secnonce->pk, pk, sizeof(secnonce->pk));
278278

279279
point_t R_s1, R_s2;
280280

281-
if (CX_OK != point_mul(G, secnonce->k_1, &R_s1)) return -1;
282-
if (CX_OK != point_mul(G, secnonce->k_2, &R_s2)) return -1;
281+
if (CX_OK != point_mul(G, secnonce->k_1, &R_s1)) goto nonce_gen_fail;
282+
if (CX_OK != point_mul(G, secnonce->k_2, &R_s2)) goto nonce_gen_fail;
283283

284-
if (0 > crypto_get_compressed_pubkey(R_s1.raw, pubnonce->R_s1)) return -1;
285-
if (0 > crypto_get_compressed_pubkey(R_s2.raw, pubnonce->R_s2)) return -1;
284+
if (0 > crypto_get_compressed_pubkey(R_s1.raw, pubnonce->R_s1)) goto nonce_gen_fail;
285+
if (0 > crypto_get_compressed_pubkey(R_s2.raw, pubnonce->R_s2)) goto nonce_gen_fail;
286286

287287
return 0;
288+
289+
nonce_gen_fail:
290+
explicit_bzero(secnonce->k_1, sizeof(secnonce->k_1));
291+
explicit_bzero(secnonce->k_2, sizeof(secnonce->k_2));
292+
return -1;
288293
}
289294

290295
int musig_nonce_agg(const musig_pubnonce_t pubnonces[], size_t n_keys, musig_pubnonce_t *out) {
@@ -484,40 +489,49 @@ int musig_sign(musig_secnonce_t *secnonce,
484489
explicit_bzero(secnonce->k_1, sizeof(secnonce->k_1));
485490
explicit_bzero(secnonce->k_2, sizeof(secnonce->k_2));
486491

492+
bool err = false;
493+
uint8_t bk_2[32];
494+
487495
if (CX_OK != cx_math_cmp_no_throw(k_1, secp256k1_n, 32, &diff)) {
488-
return -1;
496+
err = true;
497+
goto cleanup;
489498
}
490499
if (is_array_all_zeros(k_1, sizeof(k_1)) || diff >= 0) {
491500
PRINTF("first secnonce value is out of range\n");
492-
return -1;
501+
err = true;
502+
goto cleanup;
493503
}
494504
if (CX_OK != cx_math_cmp_no_throw(k_2, secp256k1_n, 32, &diff)) {
495-
return -1;
505+
err = true;
506+
goto cleanup;
496507
}
497508
if (is_array_all_zeros(k_2, sizeof(k_2)) || diff >= 0) {
498509
PRINTF("second secnonce value is out of range\n");
499-
return -1;
510+
err = true;
511+
goto cleanup;
500512
}
501513

502514
if (!has_even_y(&R)) {
503515
if (CX_OK != cx_math_sub_no_throw(k_1, secp256k1_n, k_1, 32)) {
504-
return -1;
516+
err = true;
517+
goto cleanup;
505518
};
506519
if (CX_OK != cx_math_sub_no_throw(k_2, secp256k1_n, k_2, 32)) {
507-
return -1;
520+
err = true;
521+
goto cleanup;
508522
};
509523
}
510524

511525
if (CX_OK != cx_math_cmp_no_throw(sk, secp256k1_n, 32, &diff)) {
512-
return -1;
526+
err = true;
527+
goto cleanup;
513528
}
514529
if (is_array_all_zeros(sk, 32) || diff >= 0) {
515530
PRINTF("secret key value is out of range\n");
516-
return -1;
531+
err = true;
532+
goto cleanup;
517533
}
518534

519-
bool err = false;
520-
521535
// Put together all the variables that we want to always zero out before returning.
522536
// As an excess of safety, we put here any variable that is (directly or indirectly) derived
523537
// from the secret during the computation of the signature
@@ -574,7 +588,7 @@ int musig_sign(musig_secnonce_t *secnonce,
574588
break;
575589
}
576590

577-
uint8_t bk_2[32]; // b * k_2
591+
// bk_2 = b * k_2
578592
if (CX_OK != cx_math_multm_no_throw(bk_2, b, k_2, secp256k1_n, 32)) {
579593
err = true;
580594
break;
@@ -607,6 +621,11 @@ int musig_sign(musig_secnonce_t *secnonce,
607621
// make sure to zero out any variable derived from secrets before returning
608622
explicit_bzero(&secrets, sizeof(secrets));
609623

624+
cleanup:
625+
explicit_bzero(k_1, sizeof(k_1));
626+
explicit_bzero(k_2, sizeof(k_2));
627+
explicit_bzero(bk_2, sizeof(bk_2));
628+
610629
if (err) {
611630
return -1;
612631
}

0 commit comments

Comments
 (0)