Skip to content

Commit 463712f

Browse files
sangbidarustyrussell
authored andcommitted
utils: add a generic mlock function with a destructor
Introduces a generic utility function to replace the repeated pattern of sodium_mlock() + tal_add_destructor()
1 parent 3104057 commit 463712f

File tree

7 files changed

+27
-33
lines changed

7 files changed

+27
-33
lines changed

common/hsm_secret.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@
2828
#define PASSPHRASE_HASH_LEN 32
2929
#define HSM_SECRET_PLAIN_SIZE 32
3030

31-
void destroy_secret(struct secret *secret)
32-
{
33-
sodium_munlock(secret->data, sizeof(secret->data));
34-
}
35-
3631
/* Helper function to validate a mnemonic string */
3732
static bool validate_mnemonic(const char *mnemonic, enum hsm_secret_error *err)
3833
{
@@ -70,9 +65,7 @@ struct secret *get_encryption_key(const tal_t *ctx, const char *passphrase)
7065
}
7166

7267
/* Don't swap the encryption key ! */
73-
if (sodium_mlock(secret->data, sizeof(secret->data)) != 0)
74-
return tal_free(secret);
75-
tal_add_destructor(secret, destroy_secret);
68+
mlock_tal_memory(secret);
7669

7770
/* Now derive the key. */
7871
if (crypto_pwhash(secret->data, sizeof(secret->data), passphrase, strlen(passphrase), salt,
@@ -254,10 +247,6 @@ static struct hsm_secret *extract_encrypted_secret(const tal_t *ctx,
254247
/* Attempt decryption */
255248
struct secret temp_secret;
256249
decrypt_success = decrypt_hsm_secret(encryption_key, hsm_secret, &temp_secret);
257-
258-
/* Clear encryption key immediately after use */
259-
destroy_secret(encryption_key);
260-
261250
if (!decrypt_success) {
262251
*err = HSM_SECRET_ERR_WRONG_PASSPHRASE;
263252
return tal_free(hsms);
@@ -389,11 +378,6 @@ bool encrypt_legacy_hsm_secret(const struct secret *encryption_key,
389378
return true;
390379
}
391380

392-
static void destroy_passphrase(char *passphrase)
393-
{
394-
sodium_munlock(passphrase, tal_bytelen(passphrase));
395-
}
396-
397381
/* Disable terminal echo if needed */
398382
static bool disable_echo(struct termios *saved_term)
399383
{
@@ -457,11 +441,7 @@ const char *read_stdin_pass(const tal_t *ctx, enum hsm_secret_error *err)
457441
return NULL;
458442
}
459443

460-
/* Memory locking is mandatory: failure means we're on an insecure system */
461-
if (sodium_mlock(input, tal_bytelen(input)) != 0)
462-
abort();
463-
464-
tal_add_destructor(input, destroy_passphrase);
444+
mlock_tal_memory(input);
465445

466446
if (echo_disabled)
467447
restore_echo(&saved_term);

common/hsm_secret.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,6 @@ bool derive_seed_hash(const char *mnemonic, const char *passphrase, struct sha25
158158
*/
159159
int is_legacy_hsm_secret_encrypted(const char *path);
160160

161-
/**
162-
* Zero and unlock a secret's memory.
163-
* @secret - the secret to destroy
164-
*/
165-
void destroy_secret(struct secret *secret);
166-
167161
/**
168162
* Convert hsm_secret_type enum to human-readable string.
169163
* @type - the hsm_secret_type to convert

common/utils.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <common/utils.h>
1111
#include <errno.h>
1212
#include <locale.h>
13+
#include <sodium.h>
1314

1415
const tal_t *wally_tal_ctx = NULL;
1516
secp256k1_context *secp256k1_ctx;
@@ -92,6 +93,18 @@ u8 *tal_hexdata(const tal_t *ctx, const void *str, size_t len)
9293
return data;
9394
}
9495

96+
static void destroy_munlock(const tal_t *ptr)
97+
{
98+
sodium_munlock((void *)ptr, tal_bytelen(ptr));
99+
}
100+
101+
void mlock_tal_memory(const tal_t *ptr)
102+
{
103+
if (sodium_mlock((void *)ptr, tal_bytelen(ptr)) != 0)
104+
abort();
105+
tal_add_destructor(ptr, destroy_munlock);
106+
}
107+
95108
bool tal_arr_eq_(const void *a, const void *b, size_t unused)
96109
{
97110
return memeq(a, tal_bytelen(a), b, tal_bytelen(b));

common/utils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ char *tal_hex(const tal_t *ctx, const tal_t *data);
5353
/* Allocate and fill a buffer with the data of this hex string. */
5454
u8 *tal_hexdata(const tal_t *ctx, const void *str, size_t len);
5555

56+
/**
57+
* mlock_tal_memory - lock a tal-allocated memory with sodium_mlock.
58+
* @ptr - the tal-allocated memory to lock
59+
*
60+
* This is a generic function to replace the pattern of sodium_mlock + tal_add_destructor.
61+
*
62+
* Aborts on failure (memory locking is mandatory for security).
63+
*/
64+
void mlock_tal_memory(const tal_t *ptr);
65+
5666
/* Note: p is never a complex expression, otherwise this multi-evaluates! */
5767
#define tal_arr_expand(p, s) \
5868
do { \

hsmd/hsmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ static void load_hsm(const char *passphrase)
455455
hsm_secret->mnemonic = tal_steal(hsm_secret, hsms->mnemonic);
456456

457457
/*~ Don't swap this secret data to disk for security. */
458-
sodium_mlock(hsm_secret->secret_data, tal_bytelen(hsm_secret->secret_data));
458+
mlock_tal_memory(hsm_secret->secret_data);
459459
}
460460

461461
/*~ We have a pre-init call in developer mode, to set dev flags */

hsmd/libhsmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,7 @@ u8 *hsmd_init(const u8 *secret_data, size_t secret_len, const u64 hsmd_version,
24772477

24782478
/*~ Store the secret (32 or 64 bytes) - use NULL context for persistence */
24792479
secretstuff.bip32_seed = notleak(tal_dup_arr(NULL, u8, secret_data, secret_len, 0));
2480-
sodium_mlock(secretstuff.bip32_seed, tal_bytelen(secretstuff.bip32_seed));
2480+
mlock_tal_memory(secretstuff.bip32_seed);
24812481

24822482
assert(bip32_key_version.bip32_pubkey_version == BIP32_VER_MAIN_PUBLIC
24832483
|| bip32_key_version.bip32_pubkey_version == BIP32_VER_TEST_PUBLIC);

tools/hsmtool.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,6 @@ static void encrypt_hsm(const char *hsm_secret_path)
223223
if (!encrypt_legacy_hsm_secret(encryption_key, &legacy_secret, encrypted_hsm_secret))
224224
errx(ERROR_LIBSODIUM, "Could not encrypt the hsm_secret seed.");
225225

226-
/* Securely discard the encryption key */
227-
destroy_secret(encryption_key);
228-
229226
/* Create a backup file, "just in case". */
230227
rename(hsm_secret_path, backup);
231228
fd = open(hsm_secret_path, O_CREAT|O_EXCL|O_WRONLY, 0400);

0 commit comments

Comments
 (0)