summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Xu (Hello71) <alex_y_xu@yahoo.ca>2018-08-15 19:39:45 -0400
committerAlex Xu (Hello71) <alex_y_xu@yahoo.ca>2018-08-15 19:39:45 -0400
commitd0eb997ee9f9889f184d0d52397b49a7f0dee009 (patch)
tree1d0d9ed7d2cf865e9bab5960e5ee1ac194ae8eb8 /src
parent39e07e62f471cbf40503cdc1926da6fef0cc0a3e (diff)
downloadrandom-seed-d0eb997ee9f9889f184d0d52397b49a7f0dee009.tar.xz
random-seed-d0eb997ee9f9889f184d0d52397b49a7f0dee009.zip
Stuff.
Diffstat (limited to 'src')
-rw-r--r--src/id.c92
-rw-r--r--src/id.h20
-rw-r--r--src/random-seed.c171
-rw-r--r--src/sha2.c2
-rw-r--r--src/util.c43
-rw-r--r--src/util.h2
6 files changed, 178 insertions, 152 deletions
diff --git a/src/id.c b/src/id.c
new file mode 100644
index 0000000..6095ef6
--- /dev/null
+++ b/src/id.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
+
+#include "id.h"
+#include "util.h"
+
+#ifdef HAVE_UDEV
+
+#endif
+
+#ifdef HAVE_UTIL_LINUX
+
+#endif
+
+static char *really_get_machine_id() {
+#ifdef MACHINE_ID_PATH
+ FILE *machine_id_file = fopen(MACHINE_ID_PATH, "r");
+#else
+ const char *etc_machine_id = "/etc/machine-id";
+ const char *var_lib_dbus_machine_id = "/var/lib/dbus/machine-id";
+ FILE *machine_id_file = fopen(etc_machine_id, "r");
+ if (!machine_id_file) {
+ if (errno != ENOENT)
+ fprintf(stderr, "error opening %s: %s, trying %s\n",
+ etc_machine_id, strerror(errno), var_lib_dbus_machine_id);
+ machine_id_file = fopen(var_lib_dbus_machine_id, "r");
+ }
+#endif
+
+ if (!machine_id_file) {
+ perror("couldn't open any machine-id file, last error");
+ return NULL;
+ }
+
+ char *machine_id = NULL;
+ size_t machine_id_len = 0;
+ if (getdelim(&machine_id, &machine_id_len, '\0', machine_id_file) == -1) {
+ fputs("error reading machine id file\n", stderr);
+ free(machine_id);
+ return NULL;
+ }
+
+ return machine_id;
+}
+
+size_t get_machine_id(char **machine_id) {
+ static char *c_machine_id;
+ if (!c_machine_id)
+ c_machine_id = really_get_machine_id();
+ *machine_id = c_machine_id;
+ return strlen(*machine_id);
+}
+
+size_t get_fs_id(fsid_t *fs_id, int seed_fd) {
+ struct statfs statfs_buf;
+ if (fstatfs(seed_fd, &statfs_buf) == -1) {
+ perror("error: statfs seed file: %s");
+ return false;
+ }
+
+ switch (statfs_buf.f_type) {
+ case 0x9123683e: // BTRFS_SUPER_MAGIC
+ case 0xef53: // EXT2_SUPER_MAGIC == EXT3_SUPER_MAGIC == EXT4_SUPER_MAGIC
+ case 0x3153464a: // JFS_SUPER_MAGIC
+ case 0x5346544e: // NTFS_SB_MAGIC
+ case 0x52654973: // REISERFS_SUPER_MAGIC
+ case 0x24051905: // UBIFS_SUPER_MAGIC
+ memcpy(fs_id, &statfs_buf.f_fsid, sizeof(fsid_t));
+ return sizeof(fsid_t);
+ default:
+ fprintf(stderr, "error: filesystem type 0x%08x does not have consistent f_fsid\n", (unsigned int)statfs_buf.f_type);
+ return 0;
+ }
+}
+
+void hash(const unsigned char salt[static SALT_LEN], unsigned char out[static HASH_LEN], const void *in, size_t size) {
+ assert(size < INT_MAX - SALT_LEN - 100);
+ sha256_ctx ctx;
+ sha256_init(&ctx);
+ sha256_update(&ctx, salt, SALT_LEN);
+ sha256_update(&ctx, in, (unsigned int)size);
+ sha256_final(&ctx, out);
+}
diff --git a/src/id.h b/src/id.h
new file mode 100644
index 0000000..7c45a64
--- /dev/null
+++ b/src/id.h
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
+#ifndef FSID_H
+#define FSID_H
+
+#include <sys/types.h>
+
+#include "util.h"
+
+#if defined(HAVE_UDEV) || defined(HAVE_UTIL_LINUX)
+size_t get_fs_uuid(char **fs_uuid, int seed_fd);
+#endif
+#ifdef HAVE_UDEV
+size_t get_drive_id(char **drive_id, int seed_fd);
+#endif
+size_t get_machine_id(char **machine_id);
+size_t get_fs_id(fsid_t *fs_id, int seed_fd);
+void hash(const unsigned char salt[static SALT_LEN], unsigned char *out, const void *in, size_t size);
+
+#endif
diff --git a/src/random-seed.c b/src/random-seed.c
index b8e8ad7..0ce1f8b 100644
--- a/src/random-seed.c
+++ b/src/random-seed.c
@@ -18,6 +18,8 @@
#include <unistd.h>
#include "config.h"
+
+#include "id.h"
#include "musl-libgen-c.h"
#include "util.h"
@@ -46,104 +48,55 @@ static inline void usage() {
puts("see random-seed(8) for more information.");
}
-static char *get_machine_id() {
-#ifdef MACHINE_ID_PATH
- FILE *machine_id_file = fopen(MACHINE_ID_PATH, "r");
+static bool run_seed_file_cmd(const char *cmd, const unsigned char *salt, FILE *seed_file) {
+#define HASH_ID_CMD(my_cmd, type, fn, hash_access, ...) \
+ do { \
+ if (!streq(cmd, my_cmd)) \
+ break; \
+ char *arg = strtok(NULL, " \t"); \
+ if (!arg) { \
+ fputs("error parsing seed file: expected argument " \
+ "to '" my_cmd "'\n", stderr); \
+ return false; \
+ } \
+ type fn ## _buf; \
+ unsigned char fn ## _hash[HASH_LEN]; \
+ size_t sz = fn(&fn ## _buf, ##__VA_ARGS__); \
+ if (sz == 0) { \
+ fputs("error getting " my_cmd " hash\n", stderr); \
+ return false; \
+ } \
+ hash(salt, fn ## _hash, hash_access fn ## _buf, sz); \
+ unsigned char theirdigest[HASH_LEN]; \
+ if (hex2mem(theirdigest, HASH_LEN, arg) == 0) { \
+ fputs("error decoding hex hash\n", stderr); \
+ exit(1); \
+ } \
+ if (memcmp(fn ## _hash, theirdigest, HASH_LEN)) { \
+ fputs(my_cmd " hash does not match\n", stderr); \
+ return false; \
+ } \
+ return true; \
+ } while (0)
+
+ HASH_ID_CMD("machine-id", char *, get_machine_id, );
+ HASH_ID_CMD("fs-id", fsid_t, get_fs_id, &, fileno(seed_file));
+#if defined(HAVE_UDEV) || defined(HAVE_UTIL_LINUX)
+ HASH_ID_CMD("fs-uuid", char *, get_fs_uuid, fileno(seed_file));
#else
- const char *etc_machine_id = "/etc/machine-id";
- const char *var_lib_dbus_machine_id = "/var/lib/dbus/machine-id";
- FILE *machine_id_file = fopen(etc_machine_id, "r");
- if (!machine_id_file) {
- if (errno != ENOENT)
- fprintf(stderr, "error opening %s: %s, trying %s\n",
- etc_machine_id, strerror(errno), var_lib_dbus_machine_id);
- machine_id_file = fopen(var_lib_dbus_machine_id, "r");
+ if (streq(cmd, "fs-uuid")) {
+ fputs("error: fs-uuid not supported by this random-seed\n", stderr);
+ return false;
}
#endif
-
- if (!machine_id_file) {
- perror("couldn't open any machine-id file, last error");
- return NULL;
- }
-
- char *machine_id = NULL;
- size_t machine_id_len = 0;
- if (getdelim(&machine_id, &machine_id_len, '\0', machine_id_file) == -1) {
- fputs("error reading machine id file\n", stderr);
- free(machine_id);
- return NULL;
- }
-
- return machine_id;
-}
-
-static bool get_machine_id_hash(const unsigned char salt[static SALT_LEN], unsigned char machine_id_digest[static HASH_LEN]) {
- static char *c_machine_id;
- if (!c_machine_id)
- c_machine_id = get_machine_id();
- if (!c_machine_id)
- return false;
-
- unsigned char c_machine_id_digest[HASH_LEN];
- hash(salt, c_machine_id_digest, c_machine_id, strlen(c_machine_id));
- memcpy(machine_id_digest, c_machine_id_digest, HASH_LEN);
- return true;
-}
-
-static inline bool get_fs_id_hash(const unsigned char salt[static SALT_LEN], unsigned char fsid_digest[static HASH_LEN], int seed_fd) {
- struct statfs statfs_buf;
- if (fstatfs(seed_fd, &statfs_buf) == -1) {
- fprintf(stderr, "error statfs seed file: %s, "
- "disabling entropy credit\n", strerror(errno));
+#ifdef HAVE_UDEV
+ HASH_ID_CMD("drive-id", char *, get_drive_id, fileno(seed_file));
+#else
+ if (streq(cmd, "drive-id")) {
+ fputs("error: drive-id not supported by this random-seed\n", stderr);
return false;
}
- hash(salt, fsid_digest, &statfs_buf.f_fsid, sizeof(statfs_buf.f_fsid));
- return true;
-}
-
-static bool run_seed_file_cmd(const char *cmd, const unsigned char *salt, FILE *seed_file) {
- char *arg;
- if (streq(cmd, "machine-id")) {
- arg = strtok(NULL, " \t");
- if (!arg) {
- fputs("error parsing seed file: expected argument "
- "to 'machine-id'\n", stderr);
- return false;
- }
- unsigned char machine_id_hash[HASH_LEN];
- if (!get_machine_id_hash(salt, machine_id_hash)) {
- fputs("error getting machine id hash, disabling entropy credit\n",
- stderr);
- return false;
- }
-
- if (!hash_match(machine_id_hash, arg)) {
- fputs("machine-id does not match, disabling entropy credit\n",
- stderr);
- return false;
- }
- return true;
- }
-
- if (streq(cmd, "fs-id")) {
- arg = strtok(NULL, " \t");
- if (!arg) {
- fputs("error parsing seed file: expected argument to 'fs-id'\n", stderr);
- return false;
- }
- unsigned char fs_id_hash[HASH_LEN];
- if (!get_fs_id_hash(salt, fs_id_hash, fileno(seed_file))) {
- fputs("error getting fs id hash, disabling entropy credit\n", stderr);
- return false;
- }
-
- if (!hash_match(fs_id_hash, arg)) {
- fputs("fs id does not match, disabling entropy credit\n", stderr);
- return false;
- }
- return true;
- }
-
+#endif
fprintf(stderr, "error parsing seed file: unsupported command: %s\n", cmd);
return false;
}
@@ -302,14 +255,21 @@ static bool save(const char *seed_path, unsigned char *random_buf) {
return false;
}
- unsigned char machine_id_digest[HASH_LEN];
- if (!get_machine_id_hash(random_ptr, machine_id_digest)) {
- fputs("cannot obtain machine id, aborting save\n", stderr);
- return false;
- }
- char machine_id_hash[HASH_STR_LEN];
- mem2hex(machine_id_hash, machine_id_digest, HASH_STR_LEN);
- machine_id_hash[HASH_STR_LEN-1] = '\0';
+#define GET_HASH_STR(type, hash_access, name, ...) \
+ char name ## _hash[HASH_STR_LEN]; \
+ do { \
+ type name ## _buf; \
+ size_t name ## _len = get_ ## name(&name ## _buf, ##__VA_ARGS__); \
+ if (!name ## _len) { \
+ fputs("error obtaining " #name " \n", stderr); \
+ return false; \
+ } \
+ unsigned char name ## _digest[HASH_LEN]; \
+ hash(random_ptr, name ## _digest, hash_access name ## _buf, name ## _len); \
+ mem2hex(name ## _hash, name ## _digest, HASH_LEN); \
+ } while (0)
+
+ GET_HASH_STR(char *, , machine_id);
int seed_dir_fd = -1;
int seed_fd = -1;
@@ -341,14 +301,7 @@ static bool save(const char *seed_path, unsigned char *random_buf) {
goto out;
}
- unsigned char fs_id_digest[HASH_LEN];
- if (!get_fs_id_hash(random_ptr, fs_id_digest, seed_dir_fd)) {
- fputs("cannot obtain machine id, aborting save\n", stderr);
- goto out;
- }
- char fs_id_hash[HASH_LEN*2+1];
- mem2hex(fs_id_hash, fs_id_digest, HASH_LEN);
- fs_id_hash[sizeof(fs_id_hash)-1] = '\0';
+ GET_HASH_STR(fsid_t, &, fs_id, seed_dir_fd);
seed_fd = openat(seed_dir_fd, seed_name_new, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (seed_fd == -1) {
diff --git a/src/sha2.c b/src/sha2.c
index d949537..3814562 100644
--- a/src/sha2.c
+++ b/src/sha2.c
@@ -83,7 +83,7 @@ uint32_t sha256_k[64] =
/* SHA-256 functions */
-void sha256_transf(sha256_ctx *ctx, const unsigned char *message,
+static void sha256_transf(sha256_ctx *ctx, const unsigned char *message,
unsigned int block_nb)
{
uint32_t w[64];
diff --git a/src/util.c b/src/util.c
index 908e3a2..b552afc 100644
--- a/src/util.c
+++ b/src/util.c
@@ -50,50 +50,13 @@ static const char *HEX_CHARS = "0123456789abcdef";
* \param size the number of bytes to encode
*/
void mem2hex(char *dest, const void *src, size_t size) {
- for (size_t i = 0; i < size; i++) {
+ size_t i;
+ for (i = 0; i < size; i++) {
unsigned char c = *((const unsigned char *)src + i);
dest[2*i] = HEX_CHARS[c >> 4];
dest[2*i+1] = HEX_CHARS[c & 0xf];
}
- dest[size*2] = '\0';
-}
-
-void hash(const unsigned char salt[static SALT_LEN], unsigned char *out, const void *in, size_t size) {
- assert(size < INT_MAX - SALT_LEN - 100);
-#ifdef DEBUG
- fprintf(stderr, "hashing %zu bytes starting with 0x%x ending with 0x%x\n", size, (int)((unsigned char*)in)[0], (int)((unsigned char*)in)[size-1]);
-#endif
- sha256_ctx ctx;
- sha256_init(&ctx);
- sha256_update(&ctx, salt, SALT_LEN);
- sha256_update(&ctx, in, (unsigned int)size);
- sha256_final(&ctx, out);
-}
-
-static void print_hash(const unsigned char digest[static HASH_LEN]) {
-#ifdef DEBUG
- char hash[HASH_LEN*2+1];
- mem2hex(hash, digest, HASH_LEN);
- fprintf(stderr, "hash: %s\n", hash);
-#else
- (void)digest;
-#endif
-}
-
-bool hash_match(const unsigned char digest[static HASH_LEN], const char *arg) {
- unsigned char theirdigest[HASH_LEN];
- if (hex2mem(theirdigest, sizeof(theirdigest), arg) == 0) {
- fputs("error decoding hex hash\n", stderr);
- exit(1);
- }
-#ifdef DEBUG
- fprintf(stderr, "comparing hash, theirs: %s = 0x%02x..0x%02x, ours: 0x%02x..0x%02x\n", arg, (int)theirdigest[0], (int)theirdigest[HASH_LEN-1], (int)digest[0], (int)theirdigest[HASH_LEN-1]);
- fputs(" our ", stderr);
- print_hash(digest);
- fputs("their ", stderr);
- print_hash(theirdigest);
-#endif
- return !memcmp(digest, theirdigest, HASH_LEN);
+ dest[2*i] = '\0';
}
ssize_t random_get(void *buf, size_t buflen, unsigned int flags) {
diff --git a/src/util.h b/src/util.h
index 8759cd0..11cf369 100644
--- a/src/util.h
+++ b/src/util.h
@@ -30,7 +30,5 @@ static inline bool streq(const char *s1, const char *s2) {
ssize_t random_get(void *buf, size_t buflen, unsigned int flags);
size_t hex2mem(unsigned char *dest, size_t size, const char *src);
void mem2hex(char *dest, const void *src, size_t size);
-void hash(const unsigned char salt[static SALT_LEN], unsigned char *out, const void *in, size_t size);
-bool hash_match(const unsigned char digest[static HASH_LEN], const char *arg);
#endif