@@ -279,31 +279,43 @@ static void create_hsm(int fd, const char *passphrase)
279
279
280
280
/* Always create a mnemonic-based hsm_secret */
281
281
u8 entropy [BIP39_ENTROPY_LEN_128 ];
282
- char * mnemonic ;
282
+ char * mnemonic = NULL ;
283
283
struct sha256 seed_hash ;
284
284
285
+ status_debug ("HSM: Starting create_hsm with passphrase=%s" , passphrase ? "provided" : "none" );
286
+
287
+ /* Initialize wally tal context for libwally operations */
288
+ tal_wally_start ();
289
+ status_debug ("HSM: Initialized wally tal context" );
290
+
285
291
/* Generate random entropy for new mnemonic */
286
292
randombytes_buf (entropy , sizeof (entropy ));
293
+ status_debug ("HSM: Generated random entropy" );
287
294
288
295
/* Generate mnemonic from entropy */
289
296
if (bip39_mnemonic_from_bytes (NULL , entropy , sizeof (entropy ), & mnemonic ) != WALLY_OK ) {
297
+ tal_wally_end (tmpctx );
290
298
unlink_noerr ("hsm_secret" );
291
299
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
292
300
"Failed to generate mnemonic from entropy" );
293
301
}
302
+ status_debug ("HSM: Generated mnemonic from entropy" );
294
303
295
304
if (!mnemonic ) {
305
+ tal_wally_end (tmpctx );
296
306
unlink_noerr ("hsm_secret" );
297
307
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
298
308
"Failed to get generated mnemonic" );
299
309
}
300
310
301
311
/* Derive seed hash from mnemonic + passphrase (or zero if no passphrase) */
302
312
if (!derive_seed_hash (mnemonic , passphrase , & seed_hash )) {
313
+ tal_wally_end (tmpctx );
303
314
unlink_noerr ("hsm_secret" );
304
315
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
305
316
"Failed to derive seed hash from mnemonic" );
306
317
}
318
+ status_debug ("HSM: Derived seed hash from mnemonic" );
307
319
308
320
/* Create hsm_secret format: seed_hash (32 bytes) + mnemonic */
309
321
hsm_secret_len = PASSPHRASE_HASH_LEN + strlen (mnemonic );
@@ -313,29 +325,34 @@ static void create_hsm(int fd, const char *passphrase)
313
325
memcpy (hsm_secret_data , & seed_hash , PASSPHRASE_HASH_LEN );
314
326
/* Copy mnemonic after seed hash */
315
327
memcpy (hsm_secret_data + PASSPHRASE_HASH_LEN , mnemonic , strlen (mnemonic ));
328
+ status_debug ("HSM: Created hsm_secret data structure" );
316
329
317
330
/* Derive the actual secret from mnemonic + passphrase for our global hsm_secret */
318
331
u8 bip32_seed [BIP39_SEED_LEN_512 ];
319
332
size_t bip32_seed_len ;
320
333
321
334
if (bip39_mnemonic_to_seed (mnemonic , passphrase , bip32_seed , sizeof (bip32_seed ), & bip32_seed_len ) != WALLY_OK ) {
335
+ tal_wally_end (tmpctx );
322
336
unlink_noerr ("hsm_secret" );
323
337
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
324
338
"Failed to derive seed from mnemonic" );
325
339
}
340
+ status_debug ("HSM: Derived BIP32 seed from mnemonic" );
326
341
327
342
/* Use first 32 bytes for hsm_secret */
328
343
memcpy (& hsm_secret .secret , bip32_seed , sizeof (hsm_secret .secret ));
329
344
330
- /* Clean up the mnemonic */
331
- wally_free_string (mnemonic );
332
-
345
+ /* Clean up wally allocations */
346
+ tal_wally_end (tmpctx );
347
+ status_debug ("HSM: Cleaned up wally allocations" );
348
+
333
349
/* Write the hsm_secret data to file */
334
350
if (!write_all (fd , hsm_secret_data , hsm_secret_len )) {
335
351
unlink_noerr ("hsm_secret" );
336
352
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
337
353
"writing: %s" , strerror (errno ));
338
354
}
355
+ status_debug ("HSM: Successfully wrote hsm_secret to file" );
339
356
}
340
357
341
358
/*~ We store our root secret in a "hsm_secret" file (like all of Core Lightning,
@@ -351,12 +368,16 @@ static void maybe_create_new_hsm(const char *passphrase)
351
368
int fd = open ("hsm_secret" , O_CREAT |O_EXCL |O_WRONLY , 0400 );
352
369
if (fd < 0 ) {
353
370
/* If this is not the first time we've run, it will exist. */
354
- if (errno == EEXIST )
371
+ if (errno == EEXIST ) {
372
+ status_debug ("HSM: hsm_secret file already exists, skipping creation" );
355
373
return ;
374
+ }
356
375
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
357
376
"creating: %s" , strerror (errno ));
358
377
}
359
378
379
+ status_debug ("HSM: Creating new hsm_secret file" );
380
+
360
381
/*~ Store the seed in clear. New hsm_secret files will use mnemonic format
361
382
* with passphrases, not encrypted 32-byte secrets. */
362
383
create_hsm (fd , passphrase );
@@ -403,26 +424,44 @@ static void load_hsm(const char *passphrase)
403
424
struct hsm_secret * hsms ;
404
425
enum hsm_secret_error err ;
405
426
427
+ status_debug ("HSM: Starting load_hsm with passphrase=%s" , passphrase ? "provided" : "none" );
428
+
429
+ /* Initialize wally tal context for libwally operations */
430
+ tal_wally_start ();
431
+ status_debug ("HSM: Initialized wally tal context for load_hsm" );
432
+
406
433
/* Read the hsm_secret file */
407
434
hsm_secret_contents = grab_file (tmpctx , "hsm_secret" );
408
- if (!hsm_secret_contents )
435
+ if (!hsm_secret_contents ) {
436
+ tal_wally_end (tmpctx );
409
437
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
410
438
"Could not read hsm_secret: %s" , strerror (errno ));
439
+ }
440
+ status_debug ("HSM: Successfully read hsm_secret file, size=%zu" , tal_bytelen (hsm_secret_contents ));
411
441
412
442
/* Remove the NUL terminator that grab_file adds */
413
443
tal_resize (& hsm_secret_contents , tal_bytelen (hsm_secret_contents ) - 1 );
444
+ status_debug ("HSM: Removed NUL terminator, new size=%zu" , tal_bytelen (hsm_secret_contents ));
414
445
415
446
/* Extract the secret using the new hsm_secret module */
447
+ status_debug ("HSM: Calling extract_hsm_secret" );
416
448
hsms = extract_hsm_secret (tmpctx , hsm_secret_contents ,
417
449
tal_bytelen (hsm_secret_contents ),
418
450
passphrase , & err );
419
451
if (!hsms ) {
452
+ tal_wally_end (tmpctx );
420
453
status_failed (STATUS_FAIL_INTERNAL_ERROR ,
421
454
"Failed to load hsm_secret: %s" , hsm_secret_error_str (err ));
422
455
}
456
+ status_debug ("HSM: Successfully extracted hsm_secret" );
423
457
424
458
/* Copy the extracted secret to our global hsm_secret */
425
459
memcpy (& hsm_secret , & hsms -> secret , sizeof (hsm_secret ));
460
+ status_debug ("HSM: Copied secret to global hsm_secret" );
461
+
462
+ /* Clean up wally allocations */
463
+ tal_wally_end (tmpctx );
464
+ status_debug ("HSM: Cleaned up wally allocations in load_hsm" );
426
465
}
427
466
428
467
/*~ We have a pre-init call in developer mode, to set dev flags */
@@ -462,6 +501,8 @@ static struct io_plan *init_hsm(struct io_conn *conn,
462
501
u32 minversion , maxversion ;
463
502
const u32 our_minversion = 4 , our_maxversion = 6 ;
464
503
504
+ status_debug ("HSM: Starting init_hsm" );
505
+
465
506
/* This must be lightningd. */
466
507
assert (is_lightningd (c ));
467
508
@@ -479,6 +520,8 @@ static struct io_plan *init_hsm(struct io_conn *conn,
479
520
& minversion , & maxversion , & tlvs ))
480
521
return bad_req (conn , c , msg_in );
481
522
523
+ status_debug ("HSM: Successfully parsed init message" );
524
+
482
525
/*~ Usually we don't worry about API breakage between internal daemons,
483
526
* but there are other implementations of the HSM daemon now, so we
484
527
* do at least the simplest, clearest thing. */
@@ -488,6 +531,8 @@ static struct io_plan *init_hsm(struct io_conn *conn,
488
531
minversion , maxversion ,
489
532
our_minversion , our_maxversion );
490
533
534
+ status_debug ("HSM: Version check passed" );
535
+
491
536
/*~ Don't swap this. */
492
537
sodium_mlock (hsm_secret .secret .data , sizeof (hsm_secret .secret .data ));
493
538
@@ -502,16 +547,23 @@ static struct io_plan *init_hsm(struct io_conn *conn,
502
547
const char * hsm_passphrase = NULL ;
503
548
if (tlvs && tlvs -> hsm_passphrase ) {
504
549
hsm_passphrase = (const char * )tlvs -> hsm_passphrase ;
550
+ status_debug ("HSM: Passphrase provided in TLV" );
551
+ } else {
552
+ status_debug ("HSM: No passphrase provided in TLV" );
505
553
}
506
554
507
555
/* Once we have read the init message we know which params the master
508
556
* will use */
509
557
c -> chainparams = chainparams ;
558
+ status_debug ("HSM: About to call maybe_create_new_hsm" );
510
559
maybe_create_new_hsm (hsm_passphrase );
560
+ status_debug ("HSM: About to call load_hsm" );
511
561
load_hsm (hsm_passphrase );
562
+ status_debug ("HSM: Successfully loaded hsm_secret" );
512
563
513
564
/* Define the minimum common max version for the hsmd one */
514
565
hsmd_mutual_version = maxversion < our_maxversion ? maxversion : our_maxversion ;
566
+ status_debug ("HSM: Sending init reply" );
515
567
return req_reply (conn , c , hsmd_init (hsm_secret .secret , hsmd_mutual_version ,
516
568
bip32_key_version ));
517
569
}
0 commit comments