mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-27 19:53:42 +00:00
mount-encrypted: explicitly use uint64_t for sizes
On very large HDDs, the sector count was wrapping around. Switch most calculations to bytes using uint64_t, and use BLKGETSIZE64 for checking the loopback device size. BUG=chrome-os-partner:12705 TEST=parrot build, manual testing STATUS=Fixed Change-Id: I1f7aea81151ed5cc130b1f6a05fda83f7a85150f Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/31073 Reviewed-by: Elly Jones <ellyjones@chromium.org>
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@@ -53,9 +54,9 @@ static const uint32_t kLockboxIndex = 0x20000004;
|
|||||||
static const uint32_t kLockboxSizeV1 = 0x2c;
|
static const uint32_t kLockboxSizeV1 = 0x2c;
|
||||||
static const uint32_t kLockboxSizeV2 = 0x45;
|
static const uint32_t kLockboxSizeV2 = 0x45;
|
||||||
static const uint32_t kLockboxSaltOffset = 0x5;
|
static const uint32_t kLockboxSaltOffset = 0x5;
|
||||||
static const size_t kSectorSize = 512;
|
static const uint64_t kSectorSize = 512;
|
||||||
static const size_t kExt4BlockSize = 4096;
|
static const uint64_t kExt4BlockSize = 4096;
|
||||||
static const size_t kExt4MinBytes = 16 * 1024 * 1024;
|
static const uint64_t kExt4MinBytes = 16 * 1024 * 1024;
|
||||||
static const char * const kStaticKeyDefault = "default unsafe static key";
|
static const char * const kStaticKeyDefault = "default unsafe static key";
|
||||||
static const char * const kStaticKeyFactory = "factory unsafe static key";
|
static const char * const kStaticKeyFactory = "factory unsafe static key";
|
||||||
static const char * const kStaticKeyFinalizationNeeded = "needs finalization";
|
static const char * const kStaticKeyFinalizationNeeded = "needs finalization";
|
||||||
@@ -673,14 +674,14 @@ static int finalize_from_cmdline(char *key)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spawn_resizer(const char *device, size_t blocks,
|
static void spawn_resizer(const char *device, uint64_t blocks,
|
||||||
size_t blocks_max)
|
uint64_t blocks_max)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
/* Skip resize before forking, if it's not going to happen. */
|
/* Skip resize before forking, if it's not going to happen. */
|
||||||
if (blocks >= blocks_max) {
|
if (blocks >= blocks_max) {
|
||||||
INFO("Resizing skipped. blocks:%zu >= blocks_max:%zu",
|
INFO("Resizing skipped. blocks:%" PRIu64 " >= blocks_max:%" PRIu64,
|
||||||
blocks, blocks_max);
|
blocks, blocks_max);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -723,11 +724,11 @@ static int setup_encrypted(int mode)
|
|||||||
char *encryption_key = NULL;
|
char *encryption_key = NULL;
|
||||||
int migrate_allowed = 0, migrate_needed = 0, rebuild = 0;
|
int migrate_allowed = 0, migrate_needed = 0, rebuild = 0;
|
||||||
gchar *lodev = NULL;
|
gchar *lodev = NULL;
|
||||||
size_t sectors;
|
uint64_t sectors;
|
||||||
struct bind_mount *bind;
|
struct bind_mount *bind;
|
||||||
int sparsefd;
|
int sparsefd;
|
||||||
struct statvfs stateful_statbuf;
|
struct statvfs stateful_statbuf;
|
||||||
size_t blocks_min, blocks_max;
|
uint64_t blocks_min, blocks_max;
|
||||||
|
|
||||||
/* Use the "system key" to decrypt the "encryption key" stored in
|
/* Use the "system key" to decrypt the "encryption key" stored in
|
||||||
* the stateful partition.
|
* the stateful partition.
|
||||||
@@ -764,7 +765,7 @@ static int setup_encrypted(int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rebuild) {
|
if (rebuild) {
|
||||||
off_t fs_bytes_max;
|
uint64_t fs_bytes_max;
|
||||||
|
|
||||||
/* Wipe out the old files, and ignore errors. */
|
/* Wipe out the old files, and ignore errors. */
|
||||||
unlink(key_path);
|
unlink(key_path);
|
||||||
@@ -779,8 +780,8 @@ static int setup_encrypted(int mode)
|
|||||||
fs_bytes_max *= kSizePercent;
|
fs_bytes_max *= kSizePercent;
|
||||||
fs_bytes_max *= stateful_statbuf.f_frsize;
|
fs_bytes_max *= stateful_statbuf.f_frsize;
|
||||||
|
|
||||||
INFO("Creating sparse backing file with size %llu.",
|
INFO("Creating sparse backing file with size %" PRIu64 ".",
|
||||||
(unsigned long long)fs_bytes_max);
|
fs_bytes_max);
|
||||||
|
|
||||||
/* Create the sparse file. */
|
/* Create the sparse file. */
|
||||||
sparsefd = sparse_create(block_path, fs_bytes_max);
|
sparsefd = sparse_create(block_path, fs_bytes_max);
|
||||||
@@ -805,7 +806,7 @@ static int setup_encrypted(int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get size as seen by block device. */
|
/* Get size as seen by block device. */
|
||||||
sectors = get_sectors(lodev);
|
sectors = blk_size(lodev) / kSectorSize;
|
||||||
if (!sectors) {
|
if (!sectors) {
|
||||||
ERROR("Failed to read device size");
|
ERROR("Failed to read device size");
|
||||||
goto lo_cleanup;
|
goto lo_cleanup;
|
||||||
@@ -848,8 +849,8 @@ static int setup_encrypted(int mode)
|
|||||||
blocks_max = sectors / (kExt4BlockSize / kSectorSize);
|
blocks_max = sectors / (kExt4BlockSize / kSectorSize);
|
||||||
blocks_min = kExt4MinBytes / kExt4BlockSize;
|
blocks_min = kExt4MinBytes / kExt4BlockSize;
|
||||||
if (migrate_needed && migrate_allowed) {
|
if (migrate_needed && migrate_allowed) {
|
||||||
off_t fs_bytes_min;
|
uint64_t fs_bytes_min;
|
||||||
size_t calc_blocks_min;
|
uint64_t calc_blocks_min;
|
||||||
/* When doing a migration, the new filesystem must be
|
/* When doing a migration, the new filesystem must be
|
||||||
* large enough to hold what we're going to migrate.
|
* large enough to hold what we're going to migrate.
|
||||||
* Instead of walking the bind mount sources, which would
|
* Instead of walking the bind mount sources, which would
|
||||||
@@ -863,8 +864,7 @@ static int setup_encrypted(int mode)
|
|||||||
fs_bytes_min = stateful_statbuf.f_blocks -
|
fs_bytes_min = stateful_statbuf.f_blocks -
|
||||||
stateful_statbuf.f_bfree;
|
stateful_statbuf.f_bfree;
|
||||||
fs_bytes_min *= stateful_statbuf.f_frsize;
|
fs_bytes_min *= stateful_statbuf.f_frsize;
|
||||||
DEBUG("Stateful bytes used: %llu",
|
DEBUG("Stateful bytes used: %" PRIu64 "", fs_bytes_min);
|
||||||
(unsigned long long)fs_bytes_min);
|
|
||||||
fs_bytes_min *= kMigrationSizeMultiplier;
|
fs_bytes_min *= kMigrationSizeMultiplier;
|
||||||
|
|
||||||
/* Minimum blocks needed for that many bytes. */
|
/* Minimum blocks needed for that many bytes. */
|
||||||
@@ -876,15 +876,15 @@ static int setup_encrypted(int mode)
|
|||||||
else if (calc_blocks_min < blocks_min)
|
else if (calc_blocks_min < blocks_min)
|
||||||
calc_blocks_min = blocks_min;
|
calc_blocks_min = blocks_min;
|
||||||
|
|
||||||
DEBUG("Maximum fs blocks: %zu", blocks_max);
|
DEBUG("Maximum fs blocks: %" PRIu64 "", blocks_max);
|
||||||
DEBUG("Minimum fs blocks: %zu", blocks_min);
|
DEBUG("Minimum fs blocks: %" PRIu64 "", blocks_min);
|
||||||
DEBUG("Migration blocks chosen: %zu", calc_blocks_min);
|
DEBUG("Migration blocks chosen: %" PRIu64 "", calc_blocks_min);
|
||||||
blocks_min = calc_blocks_min;
|
blocks_min = calc_blocks_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rebuild) {
|
if (rebuild) {
|
||||||
INFO("Building filesystem on %s "
|
INFO("Building filesystem on %s "
|
||||||
"(blocksize:%zu, min:%zu, max:%zu).",
|
"(blocksize:%" PRIu64 ", min:%" PRIu64 ", max:%" PRIu64 ").",
|
||||||
dmcrypt_dev, kExt4BlockSize, blocks_min, blocks_max);
|
dmcrypt_dev, kExt4BlockSize, blocks_min, blocks_max);
|
||||||
if (!filesystem_build(dmcrypt_dev, kExt4BlockSize,
|
if (!filesystem_build(dmcrypt_dev, kExt4BlockSize,
|
||||||
blocks_min, blocks_max))
|
blocks_min, blocks_max))
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -38,10 +39,10 @@ static const gchar * const kLoopTemplate = "/dev/loop%d";
|
|||||||
static const int kLoopMajor = 7;
|
static const int kLoopMajor = 7;
|
||||||
static const int kLoopMax = 8;
|
static const int kLoopMax = 8;
|
||||||
static const unsigned int kResizeStepSeconds = 2;
|
static const unsigned int kResizeStepSeconds = 2;
|
||||||
static const size_t kResizeBlocks = 32768 * 10;
|
static const uint64_t kResizeBlocks = 32768 * 10;
|
||||||
static const size_t kBlocksPerGroup = 32768;
|
static const uint64_t kBlocksPerGroup = 32768;
|
||||||
static const size_t kInodeRatioDefault = 16384;
|
static const uint64_t kInodeRatioDefault = 16384;
|
||||||
static const size_t kInodeRatioMinimum = 2048;
|
static const uint64_t kInodeRatioMinimum = 2048;
|
||||||
static const gchar * const kExt4ExtendedOptions = "discard,lazy_itable_init";
|
static const gchar * const kExt4ExtendedOptions = "discard,lazy_itable_init";
|
||||||
|
|
||||||
int remove_tree(const char *tree)
|
int remove_tree(const char *tree)
|
||||||
@@ -54,20 +55,20 @@ int remove_tree(const char *tree)
|
|||||||
return runcmd(rm, NULL);
|
return runcmd(rm, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_sectors(const char *device)
|
uint64_t blk_size(const char *device)
|
||||||
{
|
{
|
||||||
size_t sectors;
|
uint64_t bytes;
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd = open(device, O_RDONLY | O_NOFOLLOW)) < 0) {
|
if ((fd = open(device, O_RDONLY | O_NOFOLLOW)) < 0) {
|
||||||
PERROR("open(%s)", device);
|
PERROR("open(%s)", device);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, BLKGETSIZE, §ors)) {
|
if (ioctl(fd, BLKGETSIZE64, &bytes)) {
|
||||||
PERROR("ioctl(%s, BLKGETSIZE)", device);
|
PERROR("ioctl(%s, BLKGETSIZE64)", device);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
return sectors;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int runcmd(const gchar *argv[], gchar **output)
|
int runcmd(const gchar *argv[], gchar **output)
|
||||||
@@ -342,11 +343,11 @@ failed:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_setup(size_t sectors, const gchar *encryption_key, const char *name,
|
int dm_setup(uint64_t sectors, const gchar *encryption_key, const char *name,
|
||||||
const gchar *device, const char *path, int discard)
|
const gchar *device, const char *path, int discard)
|
||||||
{
|
{
|
||||||
/* Mount loopback device with dm-crypt using the encryption key. */
|
/* Mount loopback device with dm-crypt using the encryption key. */
|
||||||
gchar *table = g_strdup_printf("0 %zu crypt " \
|
gchar *table = g_strdup_printf("0 %" PRIu64 " crypt " \
|
||||||
"aes-cbc-essiv:sha256 %s " \
|
"aes-cbc-essiv:sha256 %s " \
|
||||||
"0 %s 0%s",
|
"0 %s 0%s",
|
||||||
sectors,
|
sectors,
|
||||||
@@ -425,7 +426,7 @@ char *dm_get_key(const gchar *device)
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sparse_create(const char *path, size_t size)
|
int sparse_create(const char *path, uint64_t bytes)
|
||||||
{
|
{
|
||||||
int sparsefd;
|
int sparsefd;
|
||||||
|
|
||||||
@@ -434,7 +435,7 @@ int sparse_create(const char *path, size_t size)
|
|||||||
if (sparsefd < 0)
|
if (sparsefd < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (ftruncate(sparsefd, size)) {
|
if (ftruncate(sparsefd, bytes)) {
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
|
||||||
close(sparsefd);
|
close(sparsefd);
|
||||||
@@ -460,8 +461,9 @@ out:
|
|||||||
* ------------------------------------------------------------------
|
* ------------------------------------------------------------------
|
||||||
* ceil(size_max / inode-ratio_max) * ceil(blocks_mkfs / group-ratio)
|
* ceil(size_max / inode-ratio_max) * ceil(blocks_mkfs / group-ratio)
|
||||||
*/
|
*/
|
||||||
static size_t get_inode_ratio(size_t block_bytes_in, size_t blocks_mkfs_in,
|
static uint64_t get_inode_ratio(uint64_t block_bytes_in,
|
||||||
size_t blocks_max_in)
|
uint64_t blocks_mkfs_in,
|
||||||
|
uint64_t blocks_max_in)
|
||||||
{
|
{
|
||||||
double block_bytes = (double)block_bytes_in;
|
double block_bytes = (double)block_bytes_in;
|
||||||
double blocks_mkfs = (double)blocks_mkfs_in;
|
double blocks_mkfs = (double)blocks_mkfs_in;
|
||||||
@@ -491,7 +493,7 @@ static size_t get_inode_ratio(size_t block_bytes_in, size_t blocks_mkfs_in,
|
|||||||
if (inode_ratio_mkfs < kInodeRatioMinimum)
|
if (inode_ratio_mkfs < kInodeRatioMinimum)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
return (size_t)inode_ratio_mkfs;
|
return (uint64_t)inode_ratio_mkfs;
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
return kInodeRatioDefault;
|
return kInodeRatioDefault;
|
||||||
@@ -505,20 +507,20 @@ failure:
|
|||||||
*
|
*
|
||||||
* Returns 1 on success, 0 on failure.
|
* Returns 1 on success, 0 on failure.
|
||||||
*/
|
*/
|
||||||
int filesystem_build(const char *device, size_t block_bytes, size_t blocks_min,
|
int filesystem_build(const char *device, uint64_t block_bytes,
|
||||||
size_t blocks_max)
|
uint64_t blocks_min, uint64_t blocks_max)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
size_t inode_ratio;
|
uint64_t inode_ratio;
|
||||||
|
|
||||||
gchar *blocksize = g_strdup_printf("%zu", block_bytes);
|
gchar *blocksize = g_strdup_printf("%" PRIu64, block_bytes);
|
||||||
if (!blocksize) {
|
if (!blocksize) {
|
||||||
PERROR("g_strdup_printf");
|
PERROR("g_strdup_printf");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *blocks_str;
|
gchar *blocks_str;
|
||||||
blocks_str = g_strdup_printf("%zu", blocks_min);
|
blocks_str = g_strdup_printf("%" PRIu64, blocks_min);
|
||||||
if (!blocks_str) {
|
if (!blocks_str) {
|
||||||
PERROR("g_strdup_printf");
|
PERROR("g_strdup_printf");
|
||||||
goto free_blocksize;
|
goto free_blocksize;
|
||||||
@@ -526,7 +528,7 @@ int filesystem_build(const char *device, size_t block_bytes, size_t blocks_min,
|
|||||||
|
|
||||||
gchar *extended;
|
gchar *extended;
|
||||||
if (blocks_min < blocks_max) {
|
if (blocks_min < blocks_max) {
|
||||||
extended = g_strdup_printf("%s,resize=%zu",
|
extended = g_strdup_printf("%s,resize=%" PRIu64,
|
||||||
kExt4ExtendedOptions, blocks_max);
|
kExt4ExtendedOptions, blocks_max);
|
||||||
} else {
|
} else {
|
||||||
extended = g_strdup_printf("%s", kExt4ExtendedOptions);
|
extended = g_strdup_printf("%s", kExt4ExtendedOptions);
|
||||||
@@ -537,7 +539,7 @@ int filesystem_build(const char *device, size_t block_bytes, size_t blocks_min,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inode_ratio = get_inode_ratio(block_bytes, blocks_min, blocks_max);
|
inode_ratio = get_inode_ratio(block_bytes, blocks_min, blocks_max);
|
||||||
gchar *inode_ratio_str = g_strdup_printf("%zu", inode_ratio);
|
gchar *inode_ratio_str = g_strdup_printf("%" PRIu64, inode_ratio);
|
||||||
if (!inode_ratio_str) {
|
if (!inode_ratio_str) {
|
||||||
PERROR("g_strdup_printf");
|
PERROR("g_strdup_printf");
|
||||||
goto free_extended;
|
goto free_extended;
|
||||||
@@ -582,11 +584,11 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Spawns a filesystem resizing process. */
|
/* Spawns a filesystem resizing process. */
|
||||||
int filesystem_resize(const char *device, size_t blocks, size_t blocks_max)
|
int filesystem_resize(const char *device, uint64_t blocks, uint64_t blocks_max)
|
||||||
{
|
{
|
||||||
/* Ignore resizing if we know the filesystem was built to max size. */
|
/* Ignore resizing if we know the filesystem was built to max size. */
|
||||||
if (blocks >= blocks_max) {
|
if (blocks >= blocks_max) {
|
||||||
INFO("Resizing aborted. blocks:%zu >= blocks_max:%zu",
|
INFO("Resizing aborted. blocks:%" PRIu64 " >= blocks_max:%" PRIu64,
|
||||||
blocks, blocks_max);
|
blocks, blocks_max);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -609,7 +611,7 @@ int filesystem_resize(const char *device, size_t blocks, size_t blocks_max)
|
|||||||
if (blocks > blocks_max)
|
if (blocks > blocks_max)
|
||||||
blocks = blocks_max;
|
blocks = blocks_max;
|
||||||
|
|
||||||
blocks_str = g_strdup_printf("%zu", blocks);
|
blocks_str = g_strdup_printf("%" PRIu64, blocks);
|
||||||
if (!blocks_str) {
|
if (!blocks_str) {
|
||||||
PERROR("g_strdup_printf");
|
PERROR("g_strdup_printf");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -623,7 +625,7 @@ int filesystem_resize(const char *device, size_t blocks, size_t blocks_max)
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
INFO("Resizing filesystem on %s to %zu.", device, blocks);
|
INFO("Resizing filesystem on %s to %" PRIu64 ".", device, blocks);
|
||||||
if (runcmd(resize, NULL)) {
|
if (runcmd(resize, NULL)) {
|
||||||
ERROR("resize2fs failed");
|
ERROR("resize2fs failed");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#define _MOUNT_HELPERS_H_
|
#define _MOUNT_HELPERS_H_
|
||||||
|
|
||||||
/* General utility functions. */
|
/* General utility functions. */
|
||||||
size_t get_sectors(const char *device);
|
uint64_t blk_size(const char *device);
|
||||||
int remove_tree(const char *tree);
|
int remove_tree(const char *tree);
|
||||||
int runcmd(const gchar *argv[], gchar **output);
|
int runcmd(const gchar *argv[], gchar **output);
|
||||||
int same_vfs(const char *mnt_a, const char *mnt_b);
|
int same_vfs(const char *mnt_a, const char *mnt_b);
|
||||||
@@ -22,18 +22,18 @@ int loop_detach(const gchar *loopback);
|
|||||||
int loop_detach_name(const char *name);
|
int loop_detach_name(const char *name);
|
||||||
|
|
||||||
/* Encrypted device mapper setup/teardown. */
|
/* Encrypted device mapper setup/teardown. */
|
||||||
int dm_setup(size_t sectors, const gchar *encryption_key, const char *name,
|
int dm_setup(uint64_t bytes, const gchar *encryption_key, const char *name,
|
||||||
const gchar *device, const char *path, int discard);
|
const gchar *device, const char *path, int discard);
|
||||||
int dm_teardown(const gchar *device);
|
int dm_teardown(const gchar *device);
|
||||||
char *dm_get_key(const gchar *device);
|
char *dm_get_key(const gchar *device);
|
||||||
|
|
||||||
/* Sparse file creation. */
|
/* Sparse file creation. */
|
||||||
int sparse_create(const char *path, size_t size);
|
int sparse_create(const char *path, uint64_t bytes);
|
||||||
|
|
||||||
/* Filesystem creation. */
|
/* Filesystem creation. */
|
||||||
int filesystem_build(const char *device, size_t block_bytes, size_t blocks_min,
|
int filesystem_build(const char *device, uint64_t block_bytes,
|
||||||
size_t blocks_max);
|
uint64_t blocks_min, uint64_t blocks_max);
|
||||||
int filesystem_resize(const char *device, size_t blocks, size_t blocks_max);
|
int filesystem_resize(const char *device, uint64_t blocks, uint64_t blocks_max);
|
||||||
|
|
||||||
/* Encrypted keyfile handling. */
|
/* Encrypted keyfile handling. */
|
||||||
char *keyfile_read(const char *keyfile, uint8_t *system_key);
|
char *keyfile_read(const char *keyfile, uint8_t *system_key);
|
||||||
|
|||||||
Reference in New Issue
Block a user