diff --git a/src/basic/meson.build b/src/basic/meson.build index a4f97c1fb5..8f51c76dda 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -187,6 +187,8 @@ basic_sources = files(''' ratelimit.h raw-clone.h raw-reboot.h + recovery-key.c + recovery-key.h replace-var.c replace-var.h rlimit-util.c diff --git a/src/home/modhex.c b/src/basic/recovery-key.c similarity index 51% rename from src/home/modhex.c rename to src/basic/recovery-key.c index ae5f895722..a3c4500dff 100644 --- a/src/home/modhex.c +++ b/src/basic/recovery-key.c @@ -1,10 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include - -#include "modhex.h" -#include "macro.h" #include "memory-util.h" +#include "random-util.h" +#include "recovery-key.h" const char modhex_alphabet[16] = { 'c', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'r', 't', 'u', 'v' @@ -29,24 +27,24 @@ int normalize_recovery_key(const char *password, char **ret) { l = strlen(password); if (!IN_SET(l, - MODHEX_RAW_LENGTH*2, /* syntax without dashes */ - MODHEX_FORMATTED_LENGTH-1)) /* syntax with dashes */ + RECOVERY_KEY_MODHEX_RAW_LENGTH*2, /* syntax without dashes */ + RECOVERY_KEY_MODHEX_FORMATTED_LENGTH-1)) /* syntax with dashes */ return -EINVAL; - mangled = new(char, MODHEX_FORMATTED_LENGTH); + mangled = new(char, RECOVERY_KEY_MODHEX_FORMATTED_LENGTH); if (!mangled) return -ENOMEM; - for (size_t i = 0, j = 0; i < MODHEX_RAW_LENGTH; i++) { + for (size_t i = 0, j = 0; i < RECOVERY_KEY_MODHEX_RAW_LENGTH; i++) { size_t k; int a, b; - if (l == MODHEX_RAW_LENGTH*2) + if (l == RECOVERY_KEY_MODHEX_RAW_LENGTH*2) /* Syntax without dashes */ k = i * 2; else { /* Syntax with dashes */ - assert(l == MODHEX_FORMATTED_LENGTH-1); + assert(l == RECOVERY_KEY_MODHEX_FORMATTED_LENGTH-1); k = i * 2 + i / 4; if (i > 0 && i % 4 == 0 && password[k-1] != '-') @@ -67,8 +65,42 @@ int normalize_recovery_key(const char *password, char **ret) { mangled[j++] = '-'; } - mangled[MODHEX_FORMATTED_LENGTH-1] = 0; + mangled[RECOVERY_KEY_MODHEX_FORMATTED_LENGTH-1] = 0; *ret = TAKE_PTR(mangled); return 0; } + +int make_recovery_key(char **ret) { + _cleanup_(erase_and_freep) char *formatted = NULL; + _cleanup_(erase_and_freep) uint8_t *key = NULL; + int r; + + assert(ret); + + key = new(uint8_t, RECOVERY_KEY_MODHEX_RAW_LENGTH); + if (!key) + return -ENOMEM; + + r = genuine_random_bytes(key, RECOVERY_KEY_MODHEX_RAW_LENGTH, RANDOM_BLOCK); + if (r < 0) + return r; + + /* Let's now format it as 64 modhex chars, and after each 8 chars insert a dash */ + formatted = new(char, RECOVERY_KEY_MODHEX_FORMATTED_LENGTH); + if (!formatted) + return -ENOMEM; + + for (size_t i = 0, j = 0; i < RECOVERY_KEY_MODHEX_RAW_LENGTH; i++) { + formatted[j++] = modhex_alphabet[key[i] >> 4]; + formatted[j++] = modhex_alphabet[key[i] & 0xF]; + + if (i % 4 == 3) + formatted[j++] = '-'; + } + + formatted[RECOVERY_KEY_MODHEX_FORMATTED_LENGTH-1] = 0; + + *ret = TAKE_PTR(formatted); + return 0; +} diff --git a/src/home/modhex.h b/src/basic/recovery-key.h similarity index 68% rename from src/home/modhex.h rename to src/basic/recovery-key.h index 7776ed0ee1..68e8051a93 100644 --- a/src/home/modhex.h +++ b/src/basic/recovery-key.h @@ -2,10 +2,12 @@ #pragma once /* 256 bit keys = 32 bytes */ -#define MODHEX_RAW_LENGTH 32 +#define RECOVERY_KEY_MODHEX_RAW_LENGTH 32 /* Formatted as sequences of 64 modhex characters, with dashes inserted after multiples of 8 chars (incl. trailing NUL) */ -#define MODHEX_FORMATTED_LENGTH (MODHEX_RAW_LENGTH*2/8*9) +#define RECOVERY_KEY_MODHEX_FORMATTED_LENGTH (RECOVERY_KEY_MODHEX_RAW_LENGTH*2/8*9) + +int make_recovery_key(char **ret); extern const char modhex_alphabet[16]; diff --git a/src/home/homectl-recovery-key.c b/src/home/homectl-recovery-key.c index 4a6649d25c..f1a180baca 100644 --- a/src/home/homectl-recovery-key.c +++ b/src/home/homectl-recovery-key.c @@ -5,46 +5,12 @@ #include "libcrypt-util.h" #include "locale-util.h" #include "memory-util.h" -#include "modhex.h" #include "qrcode-util.h" #include "random-util.h" +#include "recovery-key.h" #include "strv.h" #include "terminal-util.h" -static int make_recovery_key(char **ret) { - _cleanup_(erase_and_freep) char *formatted = NULL; - _cleanup_(erase_and_freep) uint8_t *key = NULL; - int r; - - assert(ret); - - key = new(uint8_t, MODHEX_RAW_LENGTH); - if (!key) - return log_oom(); - - r = genuine_random_bytes(key, MODHEX_RAW_LENGTH, RANDOM_BLOCK); - if (r < 0) - return log_error_errno(r, "Failed to gather entropy for recovery key: %m"); - - /* Let's now format it as 64 modhex chars, and after each 8 chars insert a dash */ - formatted = new(char, MODHEX_FORMATTED_LENGTH); - if (!formatted) - return log_oom(); - - for (size_t i = 0, j = 0; i < MODHEX_RAW_LENGTH; i++) { - formatted[j++] = modhex_alphabet[key[i] >> 4]; - formatted[j++] = modhex_alphabet[key[i] & 0xF]; - - if (i % 4 == 3) - formatted[j++] = '-'; - } - - formatted[MODHEX_FORMATTED_LENGTH-1] = 0; - - *ret = TAKE_PTR(formatted); - return 0; -} - static int add_privileged(JsonVariant **v, const char *hashed) { _cleanup_(json_variant_unrefp) JsonVariant *e = NULL, *w = NULL, *l = NULL; int r; @@ -144,7 +110,7 @@ int identity_add_recovery_key(JsonVariant **v) { /* First, let's generate a secret key */ r = make_recovery_key(&password); if (r < 0) - return r; + return log_error_errno(r, "Failed to generate recovery key: %m"); /* Let's UNIX hash it */ r = hash_password(password, &hashed); diff --git a/src/home/homework.c b/src/home/homework.c index b61f650662..35f3206bb0 100644 --- a/src/home/homework.c +++ b/src/home/homework.c @@ -21,9 +21,9 @@ #include "main-func.h" #include "memory-util.h" #include "missing_magic.h" -#include "modhex.h" #include "mount-util.h" #include "path-util.h" +#include "recovery-key.h" #include "rm-rf.h" #include "stat-util.h" #include "strv.h" diff --git a/src/home/meson.build b/src/home/meson.build index 444dc47619..8a879cc5d5 100644 --- a/src/home/meson.build +++ b/src/home/meson.build @@ -19,8 +19,6 @@ systemd_homework_sources = files(''' homework-quota.h homework.c homework.h - modhex.c - modhex.h user-record-util.c user-record-util.h '''.split()) @@ -52,8 +50,6 @@ systemd_homed_sources = files(''' homed-varlink.c homed-varlink.h homed.c - modhex.c - modhex.h user-record-pwquality.c user-record-pwquality.h user-record-sign.c @@ -80,8 +76,6 @@ homectl_sources = files(''' homectl-recovery-key.c homectl-recovery-key.h homectl.c - modhex.c - modhex.h user-record-pwquality.c user-record-pwquality.h user-record-util.c @@ -92,8 +86,6 @@ pam_systemd_home_sym = 'src/home/pam_systemd_home.sym' pam_systemd_home_c = files(''' home-util.c home-util.h - modhex.c - modhex.h pam_systemd_home.c user-record-util.c user-record-util.h @@ -112,11 +104,3 @@ if conf.get('ENABLE_HOMED') == 1 install_dir : pkgsysconfdir) endif endif - -tests += [ - [['src/home/test-modhex.c', - 'src/home/modhex.c', - 'src/home/modhex.h'], - [], - []], -] diff --git a/src/home/user-record-util.c b/src/home/user-record-util.c index 6bcbb56aac..b8f59c55ec 100644 --- a/src/home/user-record-util.c +++ b/src/home/user-record-util.c @@ -7,7 +7,7 @@ #include "id128-util.h" #include "libcrypt-util.h" #include "memory-util.h" -#include "modhex.h" +#include "recovery-key.h" #include "mountpoint-util.h" #include "path-util.h" #include "stat-util.h" diff --git a/src/test/meson.build b/src/test/meson.build index 3574589463..c2345bd6ee 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -212,6 +212,10 @@ tests += [ [], []], + [['src/test/test-modhex.c'], + [], + []], + [['src/test/test-libmount.c'], [], [threads, diff --git a/src/home/test-modhex.c b/src/test/test-modhex.c similarity index 99% rename from src/home/test-modhex.c rename to src/test/test-modhex.c index 1bd9061a7b..836460cec4 100644 --- a/src/home/test-modhex.c +++ b/src/test/test-modhex.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "modhex.h" +#include "recovery-key.h" #include "alloc-util.h" #include "string-util.h"