diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 13:00:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 13:00:47 +0000 |
commit | 2cb7e0aaedad73b076ea18c6900b0e86c5760d79 (patch) | |
tree | da68ca54bb79f4080079bf0828acda937593a4e1 /src/home/modhex.c | |
parent | Initial commit. (diff) | |
download | systemd-2cb7e0aaedad73b076ea18c6900b0e86c5760d79.tar.xz systemd-2cb7e0aaedad73b076ea18c6900b0e86c5760d79.zip |
Adding upstream version 247.3.upstream/247.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/home/modhex.c')
-rw-r--r-- | src/home/modhex.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/home/modhex.c b/src/home/modhex.c new file mode 100644 index 0000000..ae5f895 --- /dev/null +++ b/src/home/modhex.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <errno.h> + +#include "modhex.h" +#include "macro.h" +#include "memory-util.h" + +const char modhex_alphabet[16] = { + 'c', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'r', 't', 'u', 'v' +}; + +int decode_modhex_char(char x) { + + for (size_t i = 0; i < ELEMENTSOF(modhex_alphabet); i++) + /* Check both upper and lowercase */ + if (modhex_alphabet[i] == x || (modhex_alphabet[i] - 32) == x) + return i; + + return -EINVAL; +} + +int normalize_recovery_key(const char *password, char **ret) { + _cleanup_(erase_and_freep) char *mangled = NULL; + size_t l; + + assert(password); + assert(ret); + + l = strlen(password); + if (!IN_SET(l, + MODHEX_RAW_LENGTH*2, /* syntax without dashes */ + MODHEX_FORMATTED_LENGTH-1)) /* syntax with dashes */ + return -EINVAL; + + mangled = new(char, MODHEX_FORMATTED_LENGTH); + if (!mangled) + return -ENOMEM; + + for (size_t i = 0, j = 0; i < MODHEX_RAW_LENGTH; i++) { + size_t k; + int a, b; + + if (l == MODHEX_RAW_LENGTH*2) + /* Syntax without dashes */ + k = i * 2; + else { + /* Syntax with dashes */ + assert(l == MODHEX_FORMATTED_LENGTH-1); + k = i * 2 + i / 4; + + if (i > 0 && i % 4 == 0 && password[k-1] != '-') + return -EINVAL; + } + + a = decode_modhex_char(password[k]); + if (a < 0) + return -EINVAL; + b = decode_modhex_char(password[k+1]); + if (b < 0) + return -EINVAL; + + mangled[j++] = modhex_alphabet[a]; + mangled[j++] = modhex_alphabet[b]; + + if (i % 4 == 3) + mangled[j++] = '-'; + } + + mangled[MODHEX_FORMATTED_LENGTH-1] = 0; + + *ret = TAKE_PTR(mangled); + return 0; +} |