diff options
-rw-r--r-- | src/journal/journal-authenticate.c | 54 | ||||
-rw-r--r-- | src/journal/journal-file.c | 8 | ||||
-rw-r--r-- | src/journal/journal-file.h | 13 | ||||
-rw-r--r-- | src/journal/journal-verify.c | 66 |
4 files changed, 104 insertions, 37 deletions
diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c index 5a0314b4f6..809655e1ac 100644 --- a/src/journal/journal-authenticate.c +++ b/src/journal/journal-authenticate.c @@ -27,22 +27,6 @@ #include "journal-authenticate.h" #include "fsprg.h" -static void *fsprg_state(JournalFile *f) { - uint64_t a, b; - assert(f); - - if (!f->authenticate) - return NULL; - - a = le64toh(f->fsprg_header->header_size); - b = le64toh(f->fsprg_header->state_size); - - if (a + b > f->fsprg_size) - return NULL; - - return (uint8_t*) f->fsprg_header + a; -} - static uint64_t journal_file_tag_seqnum(JournalFile *f) { uint64_t r; @@ -67,7 +51,7 @@ int journal_file_append_tag(JournalFile *f) { if (!f->hmac_running) return 0; - log_debug("Writing tag for epoch %llu\n", (unsigned long long) FSPRG_GetEpoch(fsprg_state(f))); + log_debug("Writing tag for epoch %llu\n", (unsigned long long) FSPRG_GetEpoch(f->fsprg_state)); assert(f->hmac); @@ -103,7 +87,7 @@ static int journal_file_hmac_start(JournalFile *f) { /* Prepare HMAC for next cycle */ gcry_md_reset(f->hmac); - FSPRG_GetKey(fsprg_state(f), key, sizeof(key), 0); + FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0); gcry_md_setkey(f->hmac, key, sizeof(key)); f->hmac_running = true; @@ -118,15 +102,15 @@ static int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *e assert(epoch); assert(f->authenticate); - if (le64toh(f->fsprg_header->fsprg_start_usec) == 0 || - le64toh(f->fsprg_header->fsprg_interval_usec) == 0) + if (f->fsprg_start_usec == 0 || + f->fsprg_interval_usec == 0) return -ENOTSUP; - if (realtime < le64toh(f->fsprg_header->fsprg_start_usec)) + if (realtime < f->fsprg_start_usec) return -ESTALE; - t = realtime - le64toh(f->fsprg_header->fsprg_start_usec); - t = t / le64toh(f->fsprg_header->fsprg_interval_usec); + t = realtime - f->fsprg_start_usec; + t = t / f->fsprg_interval_usec; *epoch = t; return 0; @@ -144,7 +128,7 @@ static int journal_file_need_evolve(JournalFile *f, uint64_t realtime) { if (r < 0) return r; - epoch = FSPRG_GetEpoch(fsprg_state(f)); + epoch = FSPRG_GetEpoch(f->fsprg_state); if (epoch > goal) return -ESTALE; @@ -164,7 +148,7 @@ static int journal_file_evolve(JournalFile *f, uint64_t realtime) { if (r < 0) return r; - epoch = FSPRG_GetEpoch(fsprg_state(f)); + epoch = FSPRG_GetEpoch(f->fsprg_state); if (epoch < goal) log_debug("Evolving FSPRG key from epoch %llu to %llu.", (unsigned long long) epoch, (unsigned long long) goal); @@ -174,8 +158,8 @@ static int journal_file_evolve(JournalFile *f, uint64_t realtime) { if (epoch == goal) return 0; - FSPRG_Evolve(fsprg_state(f)); - epoch = FSPRG_GetEpoch(fsprg_state(f)); + FSPRG_Evolve(f->fsprg_state); + epoch = FSPRG_GetEpoch(f->fsprg_state); } } @@ -345,8 +329,8 @@ int journal_file_load_fsprg(JournalFile *f) { goto finish; } - f->fsprg_size = le64toh(m->header_size) + le64toh(m->state_size); - if ((uint64_t) st.st_size < f->fsprg_size) { + f->fsprg_file_size = le64toh(m->header_size) + le64toh(m->state_size); + if ((uint64_t) st.st_size < f->fsprg_file_size) { r = -ENODATA; goto finish; } @@ -362,13 +346,19 @@ int journal_file_load_fsprg(JournalFile *f) { goto finish; } - f->fsprg_header = mmap(NULL, PAGE_ALIGN(f->fsprg_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (f->fsprg_header == MAP_FAILED) { - f->fsprg_header = NULL; + 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; 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->fsprg_state = (uint8_t*) f->fsprg_file + le64toh(f->fsprg_file->header_size); + f->fsprg_state_size = le64toh(f->fsprg_file->state_size); + r = 0; finish: diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 81952a08ee..3bb1e90fb3 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -96,8 +96,12 @@ void journal_file_close(JournalFile *f) { #endif #ifdef HAVE_GCRYPT - if (f->fsprg_header) - munmap(f->fsprg_header, PAGE_ALIGN(f->fsprg_size)); + if (f->fsprg_file) + munmap(f->fsprg_file, PAGE_ALIGN(f->fsprg_file_size)); + else if (f->fsprg_state) + free(f->fsprg_state); + + free(f->fsprg_seed); if (f->hmac) gcry_md_close(f->hmac); diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h index 1da1d3b834..9d437ae791 100644 --- a/src/journal/journal-file.h +++ b/src/journal/journal-file.h @@ -73,8 +73,17 @@ typedef struct JournalFile { gcry_md_hd_t hmac; bool hmac_running; - FSPRGHeader *fsprg_header; - size_t fsprg_size; + FSPRGHeader *fsprg_file; + size_t fsprg_file_size; + + 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; diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index b4e34d18a8..f6cec1eb52 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -31,6 +31,7 @@ #include "journal-verify.h" #include "lookup3.h" #include "compress.h" +#include "fsprg.h" /* FIXME: * @@ -591,7 +592,62 @@ static int verify_entry_array( return 0; } -int journal_file_verify(JournalFile *f, const char *key) { +static int journal_file_parse_seed(JournalFile *f, const char *s) { + uint8_t *seed; + size_t seed_size, c; + const char *k; + int r; + unsigned long long start, interval; + + seed_size = FSPRG_RECOMMENDED_SEEDLEN; + seed = malloc(seed_size); + if (!seed) + return -ENOMEM; + + k = s; + for (c = 0; c < seed_size; c++) { + int x, y; + + while (*k == '-') + k++; + + x = unhexchar(*k); + if (x < 0) { + free(seed); + return -EINVAL; + } + k++; + y = unhexchar(*k); + if (y < 0) { + free(seed); + return -EINVAL; + } + k++; + + seed[c] = (uint8_t) (x * 16 + y); + } + + if (*k != '/') { + free(seed); + return -EINVAL; + } + k++; + + r = sscanf(k, "%llx-%llx", &start, &interval); + if (r != 2) { + free(seed); + return -EINVAL; + } + + f->fsprg_seed = seed; + f->fsprg_seed_size = seed_size; + f->fsprg_start_usec = start; + f->fsprg_interval_usec = interval; + + return 0; +} + +int journal_file_verify(JournalFile *f, const char *seed) { int r; Object *o; uint64_t p = 0; @@ -607,6 +663,14 @@ int journal_file_verify(JournalFile *f, const char *key) { assert(f); + if (seed) { + r = journal_file_parse_seed(f, seed); + if (r < 0) { + log_error("Failed to parse seed."); + goto fail; + } + } + data_fd = mkostemp(data_path, O_CLOEXEC); if (data_fd < 0) { log_error("Failed to create data file: %m"); |