Skip to content

Commit 1c3d4bd

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

File tree

2 files changed

+57
-20
lines changed

2 files changed

+57
-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: 42 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,54 @@ 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+
495+
if (0 > musig_get_session_values(session_ctx, &Q, gacc, tacc, b, &R, e)) {
496+
err = true;
497+
goto cleanup;
498+
}
499+
487500
if (CX_OK != cx_math_cmp_no_throw(k_1, secp256k1_n, 32, &diff)) {
488-
return -1;
501+
err = true;
502+
goto cleanup;
489503
}
490504
if (is_array_all_zeros(k_1, sizeof(k_1)) || diff >= 0) {
491505
PRINTF("first secnonce value is out of range\n");
492-
return -1;
506+
err = true;
507+
goto cleanup;
493508
}
494509
if (CX_OK != cx_math_cmp_no_throw(k_2, secp256k1_n, 32, &diff)) {
495-
return -1;
510+
err = true;
511+
goto cleanup;
496512
}
497513
if (is_array_all_zeros(k_2, sizeof(k_2)) || diff >= 0) {
498514
PRINTF("second secnonce value is out of range\n");
499-
return -1;
515+
err = true;
516+
goto cleanup;
500517
}
501518

502519
if (!has_even_y(&R)) {
503520
if (CX_OK != cx_math_sub_no_throw(k_1, secp256k1_n, k_1, 32)) {
504-
return -1;
521+
err = true;
522+
goto cleanup;
505523
};
506524
if (CX_OK != cx_math_sub_no_throw(k_2, secp256k1_n, k_2, 32)) {
507-
return -1;
525+
err = true;
526+
goto cleanup;
508527
};
509528
}
510529

511530
if (CX_OK != cx_math_cmp_no_throw(sk, secp256k1_n, 32, &diff)) {
512-
return -1;
531+
err = true;
532+
goto cleanup;
513533
}
514534
if (is_array_all_zeros(sk, 32) || diff >= 0) {
515535
PRINTF("secret key value is out of range\n");
516-
return -1;
536+
err = true;
537+
goto cleanup;
517538
}
518539

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

577-
uint8_t bk_2[32]; // b * k_2
596+
// bk_2 = b * k_2
578597
if (CX_OK != cx_math_multm_no_throw(bk_2, b, k_2, secp256k1_n, 32)) {
579598
err = true;
580599
break;
@@ -607,6 +626,11 @@ int musig_sign(musig_secnonce_t *secnonce,
607626
// make sure to zero out any variable derived from secrets before returning
608627
explicit_bzero(&secrets, sizeof(secrets));
609628

629+
cleanup:
630+
explicit_bzero(k_1, sizeof(k_1));
631+
explicit_bzero(k_2, sizeof(k_2));
632+
explicit_bzero(bk_2, sizeof(bk_2));
633+
610634
if (err) {
611635
return -1;
612636
}

0 commit comments

Comments
 (0)