assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
if (!f->hmac_running)
uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
if (f->hmac_running)
assert(f);
assert(epoch);
- assert(f->authenticate);
+ assert(f->seal);
- if (f->fsprg_start_usec == 0 ||
- f->fsprg_interval_usec == 0)
+ if (f->fss_start_usec == 0 ||
+ f->fss_interval_usec == 0)
return -ENOTSUP;
- if (realtime < f->fsprg_start_usec)
+ if (realtime < f->fss_start_usec)
return -ESTALE;
- t = realtime - f->fsprg_start_usec;
- t = t / f->fsprg_interval_usec;
+ t = realtime - f->fss_start_usec;
+ t = t / f->fss_interval_usec;
*epoch = t;
return 0;
}
-static int journal_file_need_evolve(JournalFile *f, uint64_t realtime) {
+static int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) {
uint64_t goal, epoch;
int r;
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
r = journal_file_get_epoch(f, realtime, &goal);
return epoch != goal;
}
-static int journal_file_evolve(JournalFile *f, uint64_t realtime) {
+int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) {
uint64_t goal, epoch;
int r;
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
r = journal_file_get_epoch(f, realtime, &goal);
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
assert(f->fsprg_seed);
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
- r = journal_file_need_evolve(f, realtime);
+ r = journal_file_fsprg_need_evolve(f, realtime);
if (r <= 0)
return 0;
if (r < 0)
return r;
- r = journal_file_evolve(f, realtime);
+ r = journal_file_fsprg_evolve(f, realtime);
if (r < 0)
return r;
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
r = journal_file_hmac_start(f);
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
r = journal_file_hmac_start(f);
return 0;
}
-int journal_file_load_fsprg(JournalFile *f) {
+int journal_file_fss_load(JournalFile *f) {
int r, fd = -1;
char *p = NULL;
struct stat st;
- FSPRGHeader *m = NULL;
+ FSSHeader *m = NULL;
sd_id128_t machine;
assert(f);
- if (!f->authenticate)
+ if (!f->seal)
return 0;
r = sd_id128_get_machine(&machine);
if (r < 0)
return r;
- if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fsprg",
+ if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
SD_ID128_FORMAT_VAL(machine)) < 0)
return -ENOMEM;
goto finish;
}
- if (st.st_size < (off_t) sizeof(FSPRGHeader)) {
+ if (st.st_size < (off_t) sizeof(FSSHeader)) {
r = -ENODATA;
goto finish;
}
- m = mmap(NULL, PAGE_ALIGN(sizeof(FSPRGHeader)), PROT_READ, MAP_SHARED, fd, 0);
+ m = mmap(NULL, PAGE_ALIGN(sizeof(FSSHeader)), PROT_READ, MAP_SHARED, fd, 0);
if (m == MAP_FAILED) {
m = NULL;
r = -errno;
goto finish;
}
- if (memcmp(m->signature, FSPRG_HEADER_SIGNATURE, 8) != 0) {
+ if (memcmp(m->signature, FSS_HEADER_SIGNATURE, 8) != 0) {
r = -EBADMSG;
goto finish;
}
goto finish;
}
- if (le64toh(m->header_size) < sizeof(FSPRGHeader)) {
+ if (le64toh(m->header_size) < sizeof(FSSHeader)) {
r = -EBADMSG;
goto finish;
}
- if (le64toh(m->state_size) != FSPRG_stateinbytes(m->secpar)) {
+ if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(m->fsprg_secpar)) {
r = -EBADMSG;
goto finish;
}
- f->fsprg_file_size = le64toh(m->header_size) + le64toh(m->state_size);
- if ((uint64_t) st.st_size < f->fsprg_file_size) {
+ f->fss_file_size = le64toh(m->header_size) + le64toh(m->fsprg_state_size);
+ if ((uint64_t) st.st_size < f->fss_file_size) {
r = -ENODATA;
goto finish;
}
goto finish;
}
- if (le64toh(m->fsprg_start_usec) <= 0 ||
- le64toh(m->fsprg_interval_usec) <= 0) {
+ if (le64toh(m->start_usec) <= 0 ||
+ le64toh(m->interval_usec) <= 0) {
r = -EBADMSG;
goto finish;
}
- f->fsprg_file = mmap(NULL, PAGE_ALIGN(f->fsprg_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (f->fsprg_file == MAP_FAILED) {
- f->fsprg_file = NULL;
+ f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (f->fss_file == MAP_FAILED) {
+ f->fss_file = NULL;
r = -errno;
goto finish;
}
- f->fsprg_start_usec = le64toh(f->fsprg_file->fsprg_start_usec);
- f->fsprg_interval_usec = le64toh(f->fsprg_file->fsprg_interval_usec);
+ f->fss_start_usec = le64toh(f->fss_file->start_usec);
+ f->fss_interval_usec = le64toh(f->fss_file->interval_usec);
- f->fsprg_state = (uint8_t*) f->fsprg_file + le64toh(f->fsprg_file->header_size);
- f->fsprg_state_size = le64toh(f->fsprg_file->state_size);
+ f->fsprg_state = (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size);
+ f->fsprg_state_size = le64toh(f->fss_file->fsprg_state_size);
r = 0;
finish:
if (m)
- munmap(m, PAGE_ALIGN(sizeof(FSPRGHeader)));
+ munmap(m, PAGE_ALIGN(sizeof(FSSHeader)));
if (fd >= 0)
close_nointr_nofail(fd);
return r;
}
-int journal_file_setup_hmac(JournalFile *f) {
+int journal_file_hmac_setup(JournalFile *f) {
gcry_error_t e;
- if (!f->authenticate)
+ if (!f->seal)
return 0;
e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
int r;
uint64_t p;
- if (!f->authenticate)
+ if (!f->seal)
return 0;
log_debug("Calculating first tag...");
return 0;
}
-bool journal_file_fsprg_enabled(JournalFile *f) {
+bool journal_file_fss_enabled(JournalFile *f) {
assert(f);
- return !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED);
+ return !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED);
}
int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime);
int journal_file_append_first_tag(JournalFile *f);
+int journal_file_hmac_setup(JournalFile *f);
int journal_file_hmac_start(JournalFile *f);
int journal_file_hmac_put_header(JournalFile *f);
int journal_file_hmac_put_object(JournalFile *f, int type, uint64_t p);
-int journal_file_load_fsprg(JournalFile *f);
-
-int journal_file_setup_hmac(JournalFile *f);
-
-bool journal_file_fsprg_enabled(JournalFile *f);
+int journal_file_fss_load(JournalFile *f);
+bool journal_file_fss_enabled(JournalFile *f);
+int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime);
int journal_file_fsprg_seek(JournalFile *f, uint64_t epoch);
typedef struct EntryItem EntryItem;
typedef struct HashItem HashItem;
-typedef struct FSPRGHeader FSPRGHeader;
+typedef struct FSSHeader FSSHeader;
/* Object types */
enum {
};
enum {
- HEADER_COMPATIBLE_AUTHENTICATED = 1
+ HEADER_COMPATIBLE_SEALED = 1
};
#define HEADER_SIGNATURE ((char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' })
le64_t n_entry_arrays;
};
-#define FSPRG_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' })
+#define FSS_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' })
-_packed_ struct FSPRGHeader {
+_packed_ struct FSSHeader {
uint8_t signature[8]; /* "KSHHRHLP" */
le32_t compatible_flags;
le32_t incompatible_flags;
sd_id128_t machine_id;
sd_id128_t boot_id; /* last writer */
le64_t header_size;
- le64_t fsprg_start_usec;
- le64_t fsprg_interval_usec;
- le16_t secpar;
+ le64_t start_usec;
+ le64_t interval_usec;
+ le16_t fsprg_secpar;
le16_t reserved[3];
- le64_t state_size;
+ le64_t fsprg_state_size;
};
assert(f);
/* Write the final tag */
- if (f->authenticate)
+ if (f->seal)
journal_file_append_tag(f);
/* Sync everything to disk, before we mark the file offline */
#endif
#ifdef HAVE_GCRYPT
- if (f->fsprg_file)
- munmap(f->fsprg_file, PAGE_ALIGN(f->fsprg_file_size));
+ if (f->fss_file)
+ munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size));
else if (f->fsprg_state)
free(f->fsprg_state);
htole32(f->compress ? HEADER_INCOMPATIBLE_COMPRESSED : 0);
h.compatible_flags =
- htole32(f->authenticate ? HEADER_COMPATIBLE_AUTHENTICATED : 0);
+ htole32(f->seal ? HEADER_COMPATIBLE_SEALED : 0);
r = sd_id128_randomize(&h.file_id);
if (r < 0)
* compatible flags, too */
if (f->writable) {
#ifdef HAVE_GCRYPT
- if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_AUTHENTICATED) != 0)
+ if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
return -EPROTONOSUPPORT;
#else
if (f->header->compatible_flags != 0)
if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
return -EBADMSG;
- if ((le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED) &&
- !JOURNAL_HEADER_CONTAINS(f->header, n_tags))
+ if ((le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED) &&
+ !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
return -EBADMSG;
if ((uint64_t) f->last_stat.st_size < (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
}
f->compress = !!(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED);
- f->authenticate = !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED);
+ f->seal = !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED);
return 0;
}
f->header->state == STATE_OFFLINE ? "offline" :
f->header->state == STATE_ONLINE ? "online" :
f->header->state == STATE_ARCHIVED ? "archived" : "unknown",
- (f->header->compatible_flags & HEADER_COMPATIBLE_AUTHENTICATED) ? " AUTHENTICATED" : "",
- (f->header->compatible_flags & ~HEADER_COMPATIBLE_AUTHENTICATED) ? " ???" : "",
+ (f->header->compatible_flags & HEADER_COMPATIBLE_SEALED) ? " SEALED" : "",
+ (f->header->compatible_flags & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "",
(f->header->incompatible_flags & HEADER_INCOMPATIBLE_COMPRESSED) ? " COMPRESSED" : "",
(f->header->incompatible_flags & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
(unsigned long long) le64toh(f->header->header_size),
int flags,
mode_t mode,
bool compress,
- bool authenticate,
+ bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
JournalFile *template,
f->prot = prot_from_flags(flags);
f->writable = (flags & O_ACCMODE) != O_RDONLY;
f->compress = compress;
- f->authenticate = authenticate;
+ f->seal = seal;
if (mmap_cache)
f->mmap = mmap_cache_ref(mmap_cache);
newly_created = true;
/* Try to load the FSPRG state, and if we can't, then
- * just don't do authentication */
- r = journal_file_load_fsprg(f);
+ * just don't do sealing */
+ r = journal_file_fss_load(f);
if (r < 0)
- f->authenticate = false;
+ f->seal = false;
r = journal_file_init_header(f, template);
if (r < 0)
}
if (!newly_created && f->writable) {
- r = journal_file_load_fsprg(f);
+ r = journal_file_fss_load(f);
if (r < 0)
goto fail;
}
goto fail;
}
- r = journal_file_setup_hmac(f);
+ r = journal_file_hmac_setup(f);
if (r < 0)
goto fail;
return r;
}
-int journal_file_rotate(JournalFile **f, bool compress, bool authenticate) {
+int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
char *p;
size_t l;
JournalFile *old_file, *new_file = NULL;
old_file->header->state = STATE_ARCHIVED;
- r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, authenticate, NULL, old_file->mmap, old_file, &new_file);
+ r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, old_file, &new_file);
journal_file_close(old_file);
*f = new_file;
int flags,
mode_t mode,
bool compress,
- bool authenticate,
+ bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
JournalFile *template,
size_t l;
char *p;
- r = journal_file_open(fname, flags, mode, compress, authenticate,
+ r = journal_file_open(fname, flags, mode, compress, seal,
metrics, mmap_cache, template, ret);
if (r != -EBADMSG && /* corrupted */
r != -ENODATA && /* truncated */
log_warning("File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
- return journal_file_open(fname, flags, mode, compress, authenticate,
+ return journal_file_open(fname, flags, mode, compress, seal,
metrics, mmap_cache, template, ret);
}
int prot;
bool writable;
bool compress;
- bool authenticate;
+ bool seal;
bool tail_entry_monotonic_valid;
gcry_md_hd_t hmac;
bool hmac_running;
- FSPRGHeader *fsprg_file;
- size_t fsprg_file_size;
+ FSSHeader *fss_file;
+ size_t fss_file_size;
+
+ uint64_t fss_start_usec;
+ uint64_t fss_interval_usec;
void *fsprg_state;
size_t fsprg_state_size;
void *fsprg_seed;
size_t fsprg_seed_size;
-
- uint64_t fsprg_start_usec;
- uint64_t fsprg_interval_usec;
#endif
} JournalFile;
int flags,
mode_t mode,
bool compress,
- bool authenticate,
+ bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
JournalFile *template,
int flags,
mode_t mode,
bool compress,
- bool authenticate,
+ bool seal,
JournalMetrics *metrics,
MMapCache *mmap_cache,
JournalFile *template,
void journal_file_dump(JournalFile *f);
void journal_file_print_header(JournalFile *f);
-int journal_file_rotate(JournalFile **f, bool compress, bool authenticate);
+int journal_file_rotate(JournalFile **f, bool compress, bool seal);
void journal_file_post_change(JournalFile *f);
* - write tag only if non-tag objects have been written
* - change terms
* - write bit mucking test
+ * - tag timestamps should be between entry timestamps
*
* - Allow building without libgcrypt
* - check with sparse
return 0;
}
-static int journal_file_parse_seed(JournalFile *f, const char *s) {
+static int journal_file_parse_verification_key(JournalFile *f, const char *key) {
uint8_t *seed;
size_t seed_size, c;
const char *k;
if (!seed)
return -ENOMEM;
- k = s;
+ k = key;
for (c = 0; c < seed_size; c++) {
int x, y;
f->fsprg_seed = seed;
f->fsprg_seed_size = seed_size;
- f->fsprg_start_usec = start;
- f->fsprg_interval_usec = interval;
+
+ f->fss_start_usec = start;
+ f->fss_interval_usec = interval;
return 0;
}
-int journal_file_verify(JournalFile *f, const char *seed) {
+int journal_file_verify(JournalFile *f, const char *key) {
int r;
Object *o;
uint64_t p = 0, last_tag = 0, last_epoch = 0;
assert(f);
- if (seed) {
- r = journal_file_parse_seed(f, seed);
+ if (key) {
+ r = journal_file_parse_verification_key(f, key);
if (r < 0) {
log_error("Failed to parse seed.");
return r;
case OBJECT_TAG: {
uint64_t q;
- if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED)) {
- log_error("Tag object without authentication at %llu", (unsigned long long) p);
+ if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED)) {
+ log_error("Tag object without sealing at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
}
goto fail;
if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
- log_error("Tag did not authenticate at %llu", (unsigned long long) p);
+ log_error("Tag failed verification at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
}
#include "journal-authenticate.h"
#include "fsprg.h"
-#define DEFAULT_FSPRG_INTERVAL_USEC (15*USEC_PER_MINUTE)
+#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
static OutputMode arg_output = OUTPUT_SHORT;
static bool arg_follow = false;
static bool arg_this_boot = false;
static const char *arg_directory = NULL;
static int arg_priorities = 0xFF;
-static const char *arg_verify_seed = NULL;
-static usec_t arg_evolve = DEFAULT_FSPRG_INTERVAL_USEC;
+static const char *arg_verify_key = NULL;
+static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
static enum {
ACTION_SHOW,
printf("%s [OPTIONS...] [MATCH]\n\n"
"Send control commands to or query the journal.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --no-pager Do not pipe output into a pager\n"
- " -a --all Show all fields, including long and unprintable\n"
- " -f --follow Follow journal\n"
- " -n --lines=INTEGER Journal entries to show\n"
- " --no-tail Show all lines, even in follow mode\n"
- " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
- " verbose, export, json, cat)\n"
- " -q --quiet Don't show privilege warning\n"
- " -l --local Only local entries\n"
- " -b --this-boot Show data only from current boot\n"
- " -D --directory=PATH Show journal files from directory\n"
- " -p --priority=RANGE Show only messages within the specified priority range\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " --no-pager Do not pipe output into a pager\n"
+ " -a --all Show all fields, including long and unprintable\n"
+ " -f --follow Follow journal\n"
+ " -n --lines=INTEGER Journal entries to show\n"
+ " --no-tail Show all lines, even in follow mode\n"
+ " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
+ " verbose, export, json, cat)\n"
+ " -q --quiet Don't show privilege warning\n"
+ " -l --local Only local entries\n"
+ " -b --this-boot Show data only from current boot\n"
+ " -D --directory=PATH Show journal files from directory\n"
+ " -p --priority=RANGE Show only messages within the specified priority range\n\n"
"Commands:\n"
- " --new-id128 Generate a new 128 Bit ID\n"
- " --header Show journal header information\n"
- " --verify Verify journal file consistency\n"
- " --verify-seed=SEED Specify FSPRG seed for verification\n"
- " --setup-keys Generate new FSPRG key and seed\n"
- " --evolve=TIME How of to evolve FSPRG keys\n",
+ " --new-id128 Generate a new 128 Bit ID\n"
+ " --header Show journal header information\n"
+ " --setup-keys Generate new FSS key pair\n"
+ " --interval=TIME Time interval for changing the FSS sealing key\n"
+ " --verify Verify journal file consistency\n"
+ " --verify-key=KEY Specify FSS verification key\n",
program_invocation_short_name);
return 0;
ARG_NEW_ID128,
ARG_HEADER,
ARG_SETUP_KEYS,
+ ARG_INTERVAL,
ARG_VERIFY,
- ARG_VERIFY_SEED,
- ARG_EVOLVE
+ ARG_VERIFY_KEY
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version" , no_argument, NULL, ARG_VERSION },
- { "no-pager", no_argument, NULL, ARG_NO_PAGER },
- { "follow", no_argument, NULL, 'f' },
- { "output", required_argument, NULL, 'o' },
- { "all", no_argument, NULL, 'a' },
- { "lines", required_argument, NULL, 'n' },
- { "no-tail", no_argument, NULL, ARG_NO_TAIL },
- { "new-id128", no_argument, NULL, ARG_NEW_ID128 },
- { "quiet", no_argument, NULL, 'q' },
- { "local", no_argument, NULL, 'l' },
- { "this-boot", no_argument, NULL, 'b' },
- { "directory", required_argument, NULL, 'D' },
- { "header", no_argument, NULL, ARG_HEADER },
- { "priority", no_argument, NULL, 'p' },
- { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
- { "verify", no_argument, NULL, ARG_VERIFY },
- { "verify-seed", required_argument, NULL, ARG_VERIFY_SEED },
- { "evolve", required_argument, NULL, ARG_EVOLVE },
- { NULL, 0, NULL, 0 }
+ { "help", no_argument, NULL, 'h' },
+ { "version" , no_argument, NULL, ARG_VERSION },
+ { "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "follow", no_argument, NULL, 'f' },
+ { "output", required_argument, NULL, 'o' },
+ { "all", no_argument, NULL, 'a' },
+ { "lines", required_argument, NULL, 'n' },
+ { "no-tail", no_argument, NULL, ARG_NO_TAIL },
+ { "new-id128", no_argument, NULL, ARG_NEW_ID128 },
+ { "quiet", no_argument, NULL, 'q' },
+ { "local", no_argument, NULL, 'l' },
+ { "this-boot", no_argument, NULL, 'b' },
+ { "directory", required_argument, NULL, 'D' },
+ { "header", no_argument, NULL, ARG_HEADER },
+ { "priority", no_argument, NULL, 'p' },
+ { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
+ { "interval", required_argument, NULL, ARG_INTERVAL },
+ { "verify", no_argument, NULL, ARG_VERIFY },
+ { "verify-key", required_argument, NULL, ARG_VERIFY_KEY },
+ { NULL, 0, NULL, 0 }
};
int c, r;
arg_action = ACTION_VERIFY;
break;
- case ARG_VERIFY_SEED:
+ case ARG_VERIFY_KEY:
arg_action = ACTION_VERIFY;
- arg_verify_seed = optarg;
+ arg_verify_key = optarg;
break;
- case ARG_EVOLVE:
- r = parse_usec(optarg, &arg_evolve);
- if (r < 0 || arg_evolve <= 0) {
- log_error("Failed to parse evolve interval: %s", optarg);
+ case ARG_INTERVAL:
+ r = parse_usec(optarg, &arg_interval);
+ if (r < 0 || arg_interval <= 0) {
+ log_error("Failed to parse sealing key change interval: %s", optarg);
return -EINVAL;
}
break;
int fd = -1, r;
sd_id128_t machine, boot;
char *p = NULL, *k = NULL;
- struct FSPRGHeader h;
+ struct FSSHeader h;
uint64_t n;
r = sd_id128_get_machine(&machine);
return r;
}
- if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fsprg",
+ if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
SD_ID128_FORMAT_VAL(machine)) < 0)
return log_oom();
goto finish;
}
- if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fsprg.tmp.XXXXXX",
+ if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
SD_ID128_FORMAT_VAL(machine)) < 0) {
r = log_oom();
goto finish;
log_info("Generating key pair...");
FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
- log_info("Generating evolving key...");
+ log_info("Generating sealing key...");
FSPRG_GenState0(state, mpk, seed, seed_size);
+ assert(arg_interval > 0);
+
n = now(CLOCK_REALTIME);
- n /= arg_evolve;
+ n /= arg_interval;
close_nointr_nofail(fd);
fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY);
h.machine_id = machine;
h.boot_id = boot;
h.header_size = htole64(sizeof(h));
- h.fsprg_start_usec = htole64(n * arg_evolve);
- h.fsprg_interval_usec = htole64(arg_evolve);
- h.secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
- h.state_size = htole64(state_size);
+ h.start_usec = htole64(n * arg_interval);
+ h.interval_usec = htole64(arg_interval);
+ h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
+ h.fsprg_state_size = htole64(state_size);
l = loop_write(fd, &h, sizeof(h), false);
if (l < 0 || (size_t) l != sizeof(h)) {
if (isatty(STDOUT_FILENO)) {
fprintf(stderr,
"\n"
- "The new key pair has been generated. The evolving key has been written to the\n"
- "following file. It will be used to protect local journal files. This file\n"
- "should be kept secret. It should not be used on multiple hosts.\n"
+ "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
+ "the following local file. It should not be used on multiple hosts.\n"
"\n"
"\t%s\n"
"\n"
- "Please write down the following " ANSI_HIGHLIGHT_ON "secret" ANSI_HIGHLIGHT_OFF " seed value. It should not be stored\n"
- "locally on disk, and may be used to verify journal files from this host.\n"
+ "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
+ "at a safe location and should not be saved locally on disk.\n"
"\n\t" ANSI_HIGHLIGHT_RED_ON, p);
fflush(stderr);
}
printf("%02x", ((uint8_t*) seed)[i]);
}
- printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_evolve);
+ printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
+
+ if (isatty(STDOUT_FILENO)) {
+ char tsb[FORMAT_TIMESPAN_MAX];
- if (isatty(STDOUT_FILENO))
- fputs(ANSI_HIGHLIGHT_OFF "\n", stderr);
+ fprintf(stderr,
+ ANSI_HIGHLIGHT_OFF "\n"
+ "The sealing key is automatically changed every %s.\n",
+ format_timespan(tsb, sizeof(tsb), arg_interval));
+ }
r = 0;
int k;
#ifdef HAVE_GCRYPT
- if (!arg_verify_seed && journal_file_fsprg_enabled(f))
- log_warning("Journal file %s has authentication enabled but verification seed has not been passed using --verify-seed=.", f->path);
+ if (!arg_verify_key && journal_file_fss_enabled(f))
+ log_warning("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
#endif
- k = journal_file_verify(f, arg_verify_seed);
+ k = journal_file_verify(f, arg_verify_key);
if (k == -EINVAL) {
- /* If the seed was invalid give up right-away. */
+ /* If the key was invalid give up right-away. */
return k;
} else if (k < 0) {
log_warning("FAIL: %s (%s)", f->path, strerror(-k));