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

#include <efi.h>
#include <efilib.h>

#include "memory-util-fundamental.h"
#include "missing_efi.h"
#include "random-seed.h"
#include "secure-boot.h"
#include "sha256.h"
#include "util.h"

#define RANDOM_MAX_SIZE_MIN (32U)
#define RANDOM_MAX_SIZE_MAX (32U*1024U)

struct linux_efi_random_seed {
        uint32_t size;
        uint8_t seed[];
};

#define LINUX_EFI_RANDOM_SEED_TABLE_GUID \
        { 0x1ce1e5bc, 0x7ceb, 0x42f2, { 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b } }

/* SHA256 gives us 256/8=32 bytes */
#define HASH_VALUE_SIZE 32

/* Linux's RNG is 256 bits, so let's provide this much */
#define DESIRED_SEED_SIZE 32

/* Some basic domain separation in case somebody uses this data elsewhere */
#define HASH_LABEL "systemd-boot random seed label v1"

static EFI_STATUS acquire_rng(void *ret, size_t size) {
        EFI_RNG_PROTOCOL *rng;
        EFI_STATUS err;

        assert(ret);

        /* Try to acquire the specified number of bytes from the UEFI RNG */

        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_RNG_PROTOCOL), NULL, (void **) &rng);
        if (err != EFI_SUCCESS)
                return err;
        if (!rng)
                return EFI_UNSUPPORTED;

        err = rng->GetRNG(rng, NULL, size, ret);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to acquire RNG data: %m");
        return EFI_SUCCESS;
}

static EFI_STATUS acquire_system_token(void **ret, size_t *ret_size) {
        _cleanup_free_ char *data = NULL;
        EFI_STATUS err;
        size_t size;

        assert(ret);
        assert(ret_size);

        err = efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderSystemToken", &data, &size);
        if (err != EFI_SUCCESS) {
                if (err != EFI_NOT_FOUND)
                        log_error_status(err, "Failed to read LoaderSystemToken EFI variable: %m");
                return err;
        }

        if (size <= 0)
                return log_error_status(EFI_NOT_FOUND, "System token too short, ignoring.");

        *ret = TAKE_PTR(data);
        *ret_size = size;

        return EFI_SUCCESS;
}

static void validate_sha256(void) {

#ifdef EFI_DEBUG
        /* Let's validate our SHA256 implementation. We stole it from glibc, and converted it to UEFI
         * style. We better check whether it does the right stuff. We use the simpler test vectors from the
         * SHA spec. Note that we strip this out in optimization builds. */

        static const struct {
                const char *string;
                uint8_t hash[HASH_VALUE_SIZE];
        } array[] = {
                { "abc",
                  { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
                    0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
                    0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
                    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }},

                { "",
                  { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
                    0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
                    0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
                    0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 }},

                { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
                  { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
                    0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
                    0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
                    0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }},

                { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
                  { 0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80,
                    0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37,
                    0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51,
                    0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1 }},
        };

        for (size_t i = 0; i < ELEMENTSOF(array); i++)
                assert(memcmp(SHA256_DIRECT(array[i].string, strlen8(array[i].string)), array[i].hash, HASH_VALUE_SIZE) == 0);
#endif
}

EFI_STATUS process_random_seed(EFI_FILE *root_dir) {
        uint8_t random_bytes[DESIRED_SEED_SIZE], hash_key[HASH_VALUE_SIZE];
        _cleanup_free_ struct linux_efi_random_seed *new_seed_table = NULL;
        struct linux_efi_random_seed *previous_seed_table = NULL;
        _cleanup_free_ void *seed = NULL, *system_token = NULL;
        _cleanup_(file_closep) EFI_FILE *handle = NULL;
        _cleanup_free_ EFI_FILE_INFO *info = NULL;
        struct sha256_ctx hash;
        uint64_t uefi_monotonic_counter = 0;
        size_t size, rsize, wsize;
        bool seeded_by_efi = false;
        EFI_STATUS err;
        EFI_TIME now;

        CLEANUP_ERASE(random_bytes);
        CLEANUP_ERASE(hash_key);
        CLEANUP_ERASE(hash);

        assert(root_dir);
        assert_cc(DESIRED_SEED_SIZE == HASH_VALUE_SIZE);

        validate_sha256();

        /* hash = LABEL || sizeof(input1) || input1 || ... || sizeof(inputN) || inputN */
        sha256_init_ctx(&hash);

        /* Some basic domain separation in case somebody uses this data elsewhere */
        sha256_process_bytes(HASH_LABEL, sizeof(HASH_LABEL) - 1, &hash);

        previous_seed_table = find_configuration_table(MAKE_GUID_PTR(LINUX_EFI_RANDOM_SEED_TABLE));
        if (!previous_seed_table) {
                size = 0;
                sha256_process_bytes(&size, sizeof(size), &hash);
        } else {
                size = previous_seed_table->size;
                seeded_by_efi = size >= DESIRED_SEED_SIZE;
                sha256_process_bytes(&size, sizeof(size), &hash);
                sha256_process_bytes(previous_seed_table->seed, size, &hash);

                /* Zero and free the previous seed table only at the end after we've managed to install a new
                 * one, so that in case this function fails or aborts, Linux still receives whatever the
                 * previous bootloader chain set. So, the next line of this block is not an explicit_bzero()
                 * call. */
        }

        /* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good
         * idea to use it because it helps us for cases where users mistakenly include a random seed in
         * golden master images that are replicated many times. */
        err = acquire_rng(random_bytes, sizeof(random_bytes));
        if (err != EFI_SUCCESS) {
                size = 0;
                /* If we can't get any randomness from EFI itself, then we'll only be relying on what's in
                 * ESP. But ESP is mutable, so if secure boot is enabled, we probably shouldn't trust that
                 * alone, in which case we bail out early. */
                if (!seeded_by_efi && secure_boot_enabled())
                        return EFI_NOT_FOUND;
        } else {
                seeded_by_efi = true;
                size = sizeof(random_bytes);
        }
        sha256_process_bytes(&size, sizeof(size), &hash);
        sha256_process_bytes(random_bytes, size, &hash);

        /* Get some system specific seed that the installer might have placed in an EFI variable. We include
         * it in our hash. This is protection against golden master image sloppiness, and it remains on the
         * system, even when disk images are duplicated or swapped out. */
        size = 0;
        err = acquire_system_token(&system_token, &size);
        if ((err != EFI_SUCCESS || size < DESIRED_SEED_SIZE) && !seeded_by_efi)
                return err;
        sha256_process_bytes(&size, sizeof(size), &hash);
        if (system_token) {
                sha256_process_bytes(system_token, size, &hash);
                explicit_bzero_safe(system_token, size);
        }

        err = root_dir->Open(
                        root_dir,
                        &handle,
                        (char16_t *) u"\\loader\\random-seed",
                        EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
                        0);
        if (err != EFI_SUCCESS) {
                if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED)
                        log_error_status(err, "Failed to open random seed file: %m");
                return err;
        }

        err = get_file_info_harder(handle, &info, NULL);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to get file info for random seed: %m");

        size = info->FileSize;
        if (size < RANDOM_MAX_SIZE_MIN)
                return log_error("Random seed file is too short.");

        if (size > RANDOM_MAX_SIZE_MAX)
                return log_error("Random seed file is too large.");

        seed = xmalloc(size);
        rsize = size;
        err = handle->Read(handle, &rsize, seed);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to read random seed file: %m");
        if (rsize != size) {
                explicit_bzero_safe(seed, rsize);
                return log_error_status(EFI_PROTOCOL_ERROR, "Short read on random seed file.");
        }

        sha256_process_bytes(&size, sizeof(size), &hash);
        sha256_process_bytes(seed, size, &hash);
        explicit_bzero_safe(seed, size);

        err = handle->SetPosition(handle, 0);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to seek to beginning of random seed file: %m");

        /* Let's also include the UEFI monotonic counter (which is supposedly increasing on every single
         * boot) in the hash, so that even if the changes to the ESP for some reason should not be
         * persistent, the random seed we generate will still be different on every single boot. */
        err = BS->GetNextMonotonicCount(&uefi_monotonic_counter);
        if (err != EFI_SUCCESS && !seeded_by_efi)
                return log_error_status(err, "Failed to acquire UEFI monotonic counter: %m");
        size = sizeof(uefi_monotonic_counter);
        sha256_process_bytes(&size, sizeof(size), &hash);
        sha256_process_bytes(&uefi_monotonic_counter, size, &hash);

        err = RT->GetTime(&now, NULL);
        size = err == EFI_SUCCESS ? sizeof(now) : 0; /* Known to be flaky, so don't bark on error. */
        sha256_process_bytes(&size, sizeof(size), &hash);
        sha256_process_bytes(&now, size, &hash);

        /* hash_key = HASH(hash) */
        sha256_finish_ctx(&hash, hash_key);

        /* hash = hash_key || 0 */
        sha256_init_ctx(&hash);
        sha256_process_bytes(hash_key, sizeof(hash_key), &hash);
        sha256_process_bytes(&(const uint8_t){ 0 }, sizeof(uint8_t), &hash);
        /* random_bytes = HASH(hash) */
        sha256_finish_ctx(&hash, random_bytes);

        size = sizeof(random_bytes);
        /* If the file size is too large, zero out the remaining bytes on disk. */
        if (size < info->FileSize) {
                err = handle->SetPosition(handle, size);
                if (err != EFI_SUCCESS)
                        return log_error_status(err, "Failed to seek to offset of random seed file: %m");
                wsize = info->FileSize - size;
                err = handle->Write(handle, &wsize, seed /* All zeros now */);
                if (err != EFI_SUCCESS)
                        return log_error_status(err, "Failed to write random seed file: %m");
                if (wsize != info->FileSize - size)
                        return log_error_status(EFI_PROTOCOL_ERROR, "Short write on random seed file.");
                err = handle->Flush(handle);
                if (err != EFI_SUCCESS)
                        return log_error_status(err, "Failed to flush random seed file: %m");
                err = handle->SetPosition(handle, 0);
                if (err != EFI_SUCCESS)
                        return log_error_status(err, "Failed to seek to beginning of random seed file: %m");

                /* We could truncate the file here with something like:
                 *
                 *     info->FileSize = size;
                 *     err = handle->SetInfo(handle, &GenericFileInfo, info->Size, info);
                 *     if (err != EFI_SUCCESS)
                 *             return log_error_status(err, "Failed to truncate random seed file: %u");
                 *
                 * But this is considered slightly risky, because EFI filesystem drivers are a little bit
                 * flimsy. So instead we rely on userspace eventually truncating this when it writes a new
                 * seed. For now the best we do is zero it. */
        }
        /* Update the random seed on disk before we use it */
        wsize = size;
        err = handle->Write(handle, &wsize, random_bytes);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to write random seed file: %m");
        if (wsize != size)
                return log_error_status(EFI_PROTOCOL_ERROR, "Short write on random seed file.");
        err = handle->Flush(handle);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to flush random seed file: %m");

        err = BS->AllocatePool(EfiACPIReclaimMemory,
                               offsetof(struct linux_efi_random_seed, seed) + DESIRED_SEED_SIZE,
                               (void **) &new_seed_table);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to allocate EFI table for random seed: %m");
        new_seed_table->size = DESIRED_SEED_SIZE;

        /* hash = hash_key || 1 */
        sha256_init_ctx(&hash);
        sha256_process_bytes(hash_key, sizeof(hash_key), &hash);
        sha256_process_bytes(&(const uint8_t){ 1 }, sizeof(uint8_t), &hash);
        /* new_seed_table->seed = HASH(hash) */
        sha256_finish_ctx(&hash, new_seed_table->seed);

        err = BS->InstallConfigurationTable(MAKE_GUID_PTR(LINUX_EFI_RANDOM_SEED_TABLE), new_seed_table);
        if (err != EFI_SUCCESS)
                return log_error_status(err, "Failed to install EFI table for random seed: %m");
        TAKE_PTR(new_seed_table);

        if (previous_seed_table) {
                /* Now that we've succeeded in installing the new table, we can safely nuke the old one. */
                explicit_bzero_safe(previous_seed_table->seed, previous_seed_table->size);
                explicit_bzero_safe(previous_seed_table, sizeof(*previous_seed_table));
                free(previous_seed_table);
        }

        return EFI_SUCCESS;
}
