/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "alloc-util.h"
#include "bootctl.h"
#include "bootctl-random-seed.h"
#include "bootctl-util.h"
#include "efi-api.h"
#include "env-util.h"
#include "fd-util.h"
#include "find-esp.h"
#include "fs-util.h"
#include "io-util.h"
#include "mkdir.h"
#include "path-util.h"
#include "random-util.h"
#include "sha256.h"
#include "tmpfile-util.h"
#include "umask-util.h"

static int set_system_token(void) {
        uint8_t buffer[RANDOM_EFI_SEED_SIZE];
        size_t token_size;
        int r;

        if (!arg_touch_variables)
                return 0;

        if (arg_root) {
                log_warning("Acting on %s, skipping EFI variable setup.",
                             arg_image ? "image" : "root directory");
                return 0;
        }

        if (!is_efi_boot()) {
                log_notice("Not booted with EFI, skipping EFI variable setup.");
                return 0;
        }

        r = getenv_bool("SYSTEMD_WRITE_SYSTEM_TOKEN");
        if (r < 0) {
                if (r != -ENXIO)
                        log_warning_errno(r, "Failed to parse $SYSTEMD_WRITE_SYSTEM_TOKEN, ignoring.");
        } else if (r == 0) {
                log_notice("Not writing system token, because $SYSTEMD_WRITE_SYSTEM_TOKEN is set to false.");
                return 0;
        }

        r = efi_get_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), NULL, NULL, &token_size);
        if (r == -ENODATA)
                log_debug_errno(r, "LoaderSystemToken EFI variable is invalid (too short?), replacing.");
        else if (r < 0) {
                if (r != -ENOENT)
                        return log_error_errno(r, "Failed to test system token validity: %m");
        } else {
                if (token_size >= sizeof(buffer)) {
                        /* Let's avoid writes if we can, and initialize this only once. */
                        log_debug("System token already written, not updating.");
                        return 0;
                }

                log_debug("Existing system token size (%zu) does not match our expectations (%zu), replacing.", token_size, sizeof(buffer));
        }

        r = crypto_random_bytes(buffer, sizeof(buffer));
        if (r < 0)
                return log_error_errno(r, "Failed to acquire random seed: %m");

        /* Let's write this variable with an umask in effect, so that unprivileged users can't see the token
         * and possibly get identification information or too much insight into the kernel's entropy pool
         * state. */
        WITH_UMASK(0077) {
                r = efi_set_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), buffer, sizeof(buffer));
                if (r < 0) {
                        if (!arg_graceful)
                                return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m");

                        if (r == -EINVAL)
                                log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable (firmware problem?), ignoring: %m");
                        else
                                log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m");
                } else
                        log_info("Successfully initialized system token in EFI variable with %zu bytes.", sizeof(buffer));
        }

        return 0;
}

int install_random_seed(const char *esp) {
        _cleanup_close_ int esp_fd = -EBADF, loader_dir_fd = -EBADF, fd = -EBADF;
        _cleanup_free_ char *tmp = NULL;
        uint8_t buffer[RANDOM_EFI_SEED_SIZE];
        struct sha256_ctx hash_state;
        bool refreshed;
        int r;

        assert(esp);

        assert_cc(RANDOM_EFI_SEED_SIZE == SHA256_DIGEST_SIZE);

        esp_fd = open(esp, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
        if (esp_fd < 0)
                return log_error_errno(errno, "Failed to open ESP directory '%s': %m", esp);

        loader_dir_fd = open_mkdir_at(esp_fd, "loader", O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOFOLLOW, 0775);
        if (loader_dir_fd < 0)
                return log_error_errno(loader_dir_fd, "Failed to open loader directory '%s/loader': %m", esp);

        r = crypto_random_bytes(buffer, sizeof(buffer));
        if (r < 0)
                return log_error_errno(r, "Failed to acquire random seed: %m");

        sha256_init_ctx(&hash_state);
        sha256_process_bytes_and_size(buffer, sizeof(buffer), &hash_state);

        fd = openat(loader_dir_fd, "random-seed", O_NOFOLLOW|O_CLOEXEC|O_RDONLY|O_NOCTTY);
        if (fd < 0) {
                if (errno != ENOENT)
                        return log_error_errno(errno, "Failed to open old random seed file: %m");

                sha256_process_bytes(&(const ssize_t) { 0 }, sizeof(ssize_t), &hash_state);
                refreshed = false;
        } else {
                ssize_t n;

                /* Hash the old seed in so that we never regress in entropy. */

                n = read(fd, buffer, sizeof(buffer));
                if (n < 0)
                        return log_error_errno(errno, "Failed to read old random seed file: %m");

                sha256_process_bytes_and_size(buffer, n, &hash_state);

                fd = safe_close(fd);
                refreshed = n > 0;
        }

        sha256_finish_ctx(&hash_state, buffer);

        if (tempfn_random("random-seed", "bootctl", &tmp) < 0)
                return log_oom();

        fd = openat(loader_dir_fd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
        if (fd < 0)
                return log_error_errno(fd, "Failed to open random seed file for writing: %m");

        r = loop_write(fd, buffer, sizeof(buffer), /* do_poll= */ false);
        if (r < 0) {
                log_error_errno(r, "Failed to write random seed file: %m");
                goto fail;
        }

        if (fsync(fd) < 0 || fsync(loader_dir_fd) < 0) {
                r = log_error_errno(errno, "Failed to sync random seed file: %m");
                goto fail;
        }

        if (renameat(loader_dir_fd, tmp, loader_dir_fd, "random-seed") < 0) {
                r = log_error_errno(errno, "Failed to move random seed file into place: %m");
                goto fail;
        }

        tmp = mfree(tmp);

        if (syncfs(fd) < 0)
                return log_error_errno(errno, "Failed to sync ESP file system: %m");

        log_info("Random seed file %s/loader/random-seed successfully %s (%zu bytes).", esp, refreshed ? "refreshed" : "written", sizeof(buffer));

        return set_system_token();

fail:
        assert(tmp);
        (void) unlinkat(loader_dir_fd, tmp, 0);

        return r;
}

int verb_random_seed(int argc, char *argv[], void *userdata) {
        int r;

        r = find_esp_and_warn(arg_root, arg_esp_path, false, &arg_esp_path, NULL, NULL, NULL, NULL, NULL);
        if (r == -ENOKEY) {
                /* find_esp_and_warn() doesn't warn about ENOKEY, so let's do that on our own */
                if (!arg_graceful)
                        return log_error_errno(r, "Unable to find ESP.");

                log_notice("No ESP found, not initializing random seed.");
                return 0;
        }
        if (r < 0)
                return r;

        r = install_random_seed(arg_esp_path);
        if (r < 0)
                return r;

        return 0;
}
