mirror of
https://github.com/AuxXxilium/eudev.git
synced 2025-01-26 08:59:58 +07:00
journal: rework terminology
Let's clean up our terminology a bit. New terminology: FSS = Forward Secure Sealing FSPRG = Forward Secure Pseudo-Random Generator FSS is the combination of FSPRG and a HMAC. Sealing = process of adding authentication tags to the journal. Verification = process of checking authentication tags to the journal. Sealing Key = The key used for adding authentication tags to the journal. Verification Key = The key used for checking authentication tags of the journal. Key pair = The pair of Sealing Key and Verification Key Internally, the Sealing Key is the combination of the FSPRG State plus change interval/start time. Internally, the Verification Key is the combination of the FSPRG Seed plus change interval/start time.
This commit is contained in:
parent
14d10188de
commit
baed47c3c2
@ -45,7 +45,7 @@ int journal_file_append_tag(JournalFile *f) {
|
|||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!f->hmac_running)
|
if (!f->hmac_running)
|
||||||
@ -79,7 +79,7 @@ int journal_file_hmac_start(JournalFile *f) {
|
|||||||
uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */
|
uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (f->hmac_running)
|
if (f->hmac_running)
|
||||||
@ -100,28 +100,28 @@ static int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *e
|
|||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
assert(epoch);
|
assert(epoch);
|
||||||
assert(f->authenticate);
|
assert(f->seal);
|
||||||
|
|
||||||
if (f->fsprg_start_usec == 0 ||
|
if (f->fss_start_usec == 0 ||
|
||||||
f->fsprg_interval_usec == 0)
|
f->fss_interval_usec == 0)
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
|
||||||
if (realtime < f->fsprg_start_usec)
|
if (realtime < f->fss_start_usec)
|
||||||
return -ESTALE;
|
return -ESTALE;
|
||||||
|
|
||||||
t = realtime - f->fsprg_start_usec;
|
t = realtime - f->fss_start_usec;
|
||||||
t = t / f->fsprg_interval_usec;
|
t = t / f->fss_interval_usec;
|
||||||
|
|
||||||
*epoch = t;
|
*epoch = t;
|
||||||
return 0;
|
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;
|
uint64_t goal, epoch;
|
||||||
int r;
|
int r;
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = journal_file_get_epoch(f, realtime, &goal);
|
r = journal_file_get_epoch(f, realtime, &goal);
|
||||||
@ -135,13 +135,13 @@ static int journal_file_need_evolve(JournalFile *f, uint64_t realtime) {
|
|||||||
return epoch != 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;
|
uint64_t goal, epoch;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = journal_file_get_epoch(f, realtime, &goal);
|
r = journal_file_get_epoch(f, realtime, &goal);
|
||||||
@ -169,7 +169,7 @@ int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
|
|||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
assert(f->fsprg_seed);
|
assert(f->fsprg_seed);
|
||||||
@ -206,10 +206,10 @@ int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
|
|||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = journal_file_need_evolve(f, realtime);
|
r = journal_file_fsprg_need_evolve(f, realtime);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = journal_file_evolve(f, realtime);
|
r = journal_file_fsprg_evolve(f, realtime);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ int journal_file_hmac_put_object(JournalFile *f, int type, uint64_t p) {
|
|||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = journal_file_hmac_start(f);
|
r = journal_file_hmac_start(f);
|
||||||
@ -283,7 +283,7 @@ int journal_file_hmac_put_header(JournalFile *f) {
|
|||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = journal_file_hmac_start(f);
|
r = journal_file_hmac_start(f);
|
||||||
@ -305,23 +305,23 @@ int journal_file_hmac_put_header(JournalFile *f) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int journal_file_load_fsprg(JournalFile *f) {
|
int journal_file_fss_load(JournalFile *f) {
|
||||||
int r, fd = -1;
|
int r, fd = -1;
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FSPRGHeader *m = NULL;
|
FSSHeader *m = NULL;
|
||||||
sd_id128_t machine;
|
sd_id128_t machine;
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = sd_id128_get_machine(&machine);
|
r = sd_id128_get_machine(&machine);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
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)
|
SD_ID128_FORMAT_VAL(machine)) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -337,19 +337,19 @@ int journal_file_load_fsprg(JournalFile *f) {
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_size < (off_t) sizeof(FSPRGHeader)) {
|
if (st.st_size < (off_t) sizeof(FSSHeader)) {
|
||||||
r = -ENODATA;
|
r = -ENODATA;
|
||||||
goto finish;
|
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) {
|
if (m == MAP_FAILED) {
|
||||||
m = NULL;
|
m = NULL;
|
||||||
r = -errno;
|
r = -errno;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(m->signature, FSPRG_HEADER_SIGNATURE, 8) != 0) {
|
if (memcmp(m->signature, FSS_HEADER_SIGNATURE, 8) != 0) {
|
||||||
r = -EBADMSG;
|
r = -EBADMSG;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
@ -359,18 +359,18 @@ int journal_file_load_fsprg(JournalFile *f) {
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (le64toh(m->header_size) < sizeof(FSPRGHeader)) {
|
if (le64toh(m->header_size) < sizeof(FSSHeader)) {
|
||||||
r = -EBADMSG;
|
r = -EBADMSG;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (le64toh(m->state_size) != FSPRG_stateinbytes(m->secpar)) {
|
if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(m->fsprg_secpar)) {
|
||||||
r = -EBADMSG;
|
r = -EBADMSG;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->fsprg_file_size = le64toh(m->header_size) + le64toh(m->state_size);
|
f->fss_file_size = le64toh(m->header_size) + le64toh(m->fsprg_state_size);
|
||||||
if ((uint64_t) st.st_size < f->fsprg_file_size) {
|
if ((uint64_t) st.st_size < f->fss_file_size) {
|
||||||
r = -ENODATA;
|
r = -ENODATA;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
@ -380,30 +380,30 @@ int journal_file_load_fsprg(JournalFile *f) {
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (le64toh(m->fsprg_start_usec) <= 0 ||
|
if (le64toh(m->start_usec) <= 0 ||
|
||||||
le64toh(m->fsprg_interval_usec) <= 0) {
|
le64toh(m->interval_usec) <= 0) {
|
||||||
r = -EBADMSG;
|
r = -EBADMSG;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->fsprg_file = mmap(NULL, PAGE_ALIGN(f->fsprg_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
if (f->fsprg_file == MAP_FAILED) {
|
if (f->fss_file == MAP_FAILED) {
|
||||||
f->fsprg_file = NULL;
|
f->fss_file = NULL;
|
||||||
r = -errno;
|
r = -errno;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->fsprg_start_usec = le64toh(f->fsprg_file->fsprg_start_usec);
|
f->fss_start_usec = le64toh(f->fss_file->start_usec);
|
||||||
f->fsprg_interval_usec = le64toh(f->fsprg_file->fsprg_interval_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 = (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size);
|
||||||
f->fsprg_state_size = le64toh(f->fsprg_file->state_size);
|
f->fsprg_state_size = le64toh(f->fss_file->fsprg_state_size);
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
if (m)
|
if (m)
|
||||||
munmap(m, PAGE_ALIGN(sizeof(FSPRGHeader)));
|
munmap(m, PAGE_ALIGN(sizeof(FSSHeader)));
|
||||||
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close_nointr_nofail(fd);
|
close_nointr_nofail(fd);
|
||||||
@ -412,10 +412,10 @@ finish:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int journal_file_setup_hmac(JournalFile *f) {
|
int journal_file_hmac_setup(JournalFile *f) {
|
||||||
gcry_error_t e;
|
gcry_error_t e;
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
|
e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
|
||||||
@ -429,7 +429,7 @@ int journal_file_append_first_tag(JournalFile *f) {
|
|||||||
int r;
|
int r;
|
||||||
uint64_t p;
|
uint64_t p;
|
||||||
|
|
||||||
if (!f->authenticate)
|
if (!f->seal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug("Calculating first tag...");
|
log_debug("Calculating first tag...");
|
||||||
@ -463,8 +463,8 @@ int journal_file_append_first_tag(JournalFile *f) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool journal_file_fsprg_enabled(JournalFile *f) {
|
bool journal_file_fss_enabled(JournalFile *f) {
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
return !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED);
|
return !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED);
|
||||||
}
|
}
|
||||||
|
@ -30,14 +30,13 @@ int journal_file_append_tag(JournalFile *f);
|
|||||||
int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime);
|
int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime);
|
||||||
int journal_file_append_first_tag(JournalFile *f);
|
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_start(JournalFile *f);
|
||||||
int journal_file_hmac_put_header(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_hmac_put_object(JournalFile *f, int type, uint64_t p);
|
||||||
|
|
||||||
int journal_file_load_fsprg(JournalFile *f);
|
int journal_file_fss_load(JournalFile *f);
|
||||||
|
bool journal_file_fss_enabled(JournalFile *f);
|
||||||
int journal_file_setup_hmac(JournalFile *f);
|
|
||||||
|
|
||||||
bool journal_file_fsprg_enabled(JournalFile *f);
|
|
||||||
|
|
||||||
|
int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime);
|
||||||
int journal_file_fsprg_seek(JournalFile *f, uint64_t epoch);
|
int journal_file_fsprg_seek(JournalFile *f, uint64_t epoch);
|
||||||
|
@ -42,7 +42,7 @@ typedef struct TagObject TagObject;
|
|||||||
typedef struct EntryItem EntryItem;
|
typedef struct EntryItem EntryItem;
|
||||||
typedef struct HashItem HashItem;
|
typedef struct HashItem HashItem;
|
||||||
|
|
||||||
typedef struct FSPRGHeader FSPRGHeader;
|
typedef struct FSSHeader FSSHeader;
|
||||||
|
|
||||||
/* Object types */
|
/* Object types */
|
||||||
enum {
|
enum {
|
||||||
@ -151,7 +151,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HEADER_COMPATIBLE_AUTHENTICATED = 1
|
HEADER_COMPATIBLE_SEALED = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HEADER_SIGNATURE ((char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' })
|
#define HEADER_SIGNATURE ((char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' })
|
||||||
@ -189,18 +189,18 @@ _packed_ struct Header {
|
|||||||
le64_t n_entry_arrays;
|
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" */
|
uint8_t signature[8]; /* "KSHHRHLP" */
|
||||||
le32_t compatible_flags;
|
le32_t compatible_flags;
|
||||||
le32_t incompatible_flags;
|
le32_t incompatible_flags;
|
||||||
sd_id128_t machine_id;
|
sd_id128_t machine_id;
|
||||||
sd_id128_t boot_id; /* last writer */
|
sd_id128_t boot_id; /* last writer */
|
||||||
le64_t header_size;
|
le64_t header_size;
|
||||||
le64_t fsprg_start_usec;
|
le64_t start_usec;
|
||||||
le64_t fsprg_interval_usec;
|
le64_t interval_usec;
|
||||||
le16_t secpar;
|
le16_t fsprg_secpar;
|
||||||
le16_t reserved[3];
|
le16_t reserved[3];
|
||||||
le64_t state_size;
|
le64_t fsprg_state_size;
|
||||||
};
|
};
|
||||||
|
@ -65,7 +65,7 @@ void journal_file_close(JournalFile *f) {
|
|||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
/* Write the final tag */
|
/* Write the final tag */
|
||||||
if (f->authenticate)
|
if (f->seal)
|
||||||
journal_file_append_tag(f);
|
journal_file_append_tag(f);
|
||||||
|
|
||||||
/* Sync everything to disk, before we mark the file offline */
|
/* Sync everything to disk, before we mark the file offline */
|
||||||
@ -96,8 +96,8 @@ void journal_file_close(JournalFile *f) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_GCRYPT
|
#ifdef HAVE_GCRYPT
|
||||||
if (f->fsprg_file)
|
if (f->fss_file)
|
||||||
munmap(f->fsprg_file, PAGE_ALIGN(f->fsprg_file_size));
|
munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size));
|
||||||
else if (f->fsprg_state)
|
else if (f->fsprg_state)
|
||||||
free(f->fsprg_state);
|
free(f->fsprg_state);
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ static int journal_file_init_header(JournalFile *f, JournalFile *template) {
|
|||||||
htole32(f->compress ? HEADER_INCOMPATIBLE_COMPRESSED : 0);
|
htole32(f->compress ? HEADER_INCOMPATIBLE_COMPRESSED : 0);
|
||||||
|
|
||||||
h.compatible_flags =
|
h.compatible_flags =
|
||||||
htole32(f->authenticate ? HEADER_COMPATIBLE_AUTHENTICATED : 0);
|
htole32(f->seal ? HEADER_COMPATIBLE_SEALED : 0);
|
||||||
|
|
||||||
r = sd_id128_randomize(&h.file_id);
|
r = sd_id128_randomize(&h.file_id);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -195,7 +195,7 @@ static int journal_file_verify_header(JournalFile *f) {
|
|||||||
* compatible flags, too */
|
* compatible flags, too */
|
||||||
if (f->writable) {
|
if (f->writable) {
|
||||||
#ifdef HAVE_GCRYPT
|
#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;
|
return -EPROTONOSUPPORT;
|
||||||
#else
|
#else
|
||||||
if (f->header->compatible_flags != 0)
|
if (f->header->compatible_flags != 0)
|
||||||
@ -207,8 +207,8 @@ static int journal_file_verify_header(JournalFile *f) {
|
|||||||
if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
|
if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
if ((le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED) &&
|
if ((le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED) &&
|
||||||
!JOURNAL_HEADER_CONTAINS(f->header, n_tags))
|
!JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
if ((uint64_t) f->last_stat.st_size < (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
|
if ((uint64_t) f->last_stat.st_size < (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
|
||||||
@ -240,7 +240,7 @@ static int journal_file_verify_header(JournalFile *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
f->compress = !!(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1900,8 +1900,8 @@ void journal_file_print_header(JournalFile *f) {
|
|||||||
f->header->state == STATE_OFFLINE ? "offline" :
|
f->header->state == STATE_OFFLINE ? "offline" :
|
||||||
f->header->state == STATE_ONLINE ? "online" :
|
f->header->state == STATE_ONLINE ? "online" :
|
||||||
f->header->state == STATE_ARCHIVED ? "archived" : "unknown",
|
f->header->state == STATE_ARCHIVED ? "archived" : "unknown",
|
||||||
(f->header->compatible_flags & HEADER_COMPATIBLE_AUTHENTICATED) ? " AUTHENTICATED" : "",
|
(f->header->compatible_flags & HEADER_COMPATIBLE_SEALED) ? " SEALED" : "",
|
||||||
(f->header->compatible_flags & ~HEADER_COMPATIBLE_AUTHENTICATED) ? " ???" : "",
|
(f->header->compatible_flags & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "",
|
||||||
(f->header->incompatible_flags & HEADER_INCOMPATIBLE_COMPRESSED) ? " COMPRESSED" : "",
|
(f->header->incompatible_flags & HEADER_INCOMPATIBLE_COMPRESSED) ? " COMPRESSED" : "",
|
||||||
(f->header->incompatible_flags & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
|
(f->header->incompatible_flags & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
|
||||||
(unsigned long long) le64toh(f->header->header_size),
|
(unsigned long long) le64toh(f->header->header_size),
|
||||||
@ -1934,7 +1934,7 @@ int journal_file_open(
|
|||||||
int flags,
|
int flags,
|
||||||
mode_t mode,
|
mode_t mode,
|
||||||
bool compress,
|
bool compress,
|
||||||
bool authenticate,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
@ -1964,7 +1964,7 @@ int journal_file_open(
|
|||||||
f->prot = prot_from_flags(flags);
|
f->prot = prot_from_flags(flags);
|
||||||
f->writable = (flags & O_ACCMODE) != O_RDONLY;
|
f->writable = (flags & O_ACCMODE) != O_RDONLY;
|
||||||
f->compress = compress;
|
f->compress = compress;
|
||||||
f->authenticate = authenticate;
|
f->seal = seal;
|
||||||
|
|
||||||
if (mmap_cache)
|
if (mmap_cache)
|
||||||
f->mmap = mmap_cache_ref(mmap_cache);
|
f->mmap = mmap_cache_ref(mmap_cache);
|
||||||
@ -2000,10 +2000,10 @@ int journal_file_open(
|
|||||||
newly_created = true;
|
newly_created = true;
|
||||||
|
|
||||||
/* Try to load the FSPRG state, and if we can't, then
|
/* Try to load the FSPRG state, and if we can't, then
|
||||||
* just don't do authentication */
|
* just don't do sealing */
|
||||||
r = journal_file_load_fsprg(f);
|
r = journal_file_fss_load(f);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
f->authenticate = false;
|
f->seal = false;
|
||||||
|
|
||||||
r = journal_file_init_header(f, template);
|
r = journal_file_init_header(f, template);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -2034,7 +2034,7 @@ int journal_file_open(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!newly_created && f->writable) {
|
if (!newly_created && f->writable) {
|
||||||
r = journal_file_load_fsprg(f);
|
r = journal_file_fss_load(f);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -2051,7 +2051,7 @@ int journal_file_open(
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = journal_file_setup_hmac(f);
|
r = journal_file_hmac_setup(f);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -2088,7 +2088,7 @@ fail:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int journal_file_rotate(JournalFile **f, bool compress, bool authenticate) {
|
int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
|
||||||
char *p;
|
char *p;
|
||||||
size_t l;
|
size_t l;
|
||||||
JournalFile *old_file, *new_file = NULL;
|
JournalFile *old_file, *new_file = NULL;
|
||||||
@ -2127,7 +2127,7 @@ int journal_file_rotate(JournalFile **f, bool compress, bool authenticate) {
|
|||||||
|
|
||||||
old_file->header->state = STATE_ARCHIVED;
|
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);
|
journal_file_close(old_file);
|
||||||
|
|
||||||
*f = new_file;
|
*f = new_file;
|
||||||
@ -2139,7 +2139,7 @@ int journal_file_open_reliably(
|
|||||||
int flags,
|
int flags,
|
||||||
mode_t mode,
|
mode_t mode,
|
||||||
bool compress,
|
bool compress,
|
||||||
bool authenticate,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
@ -2149,7 +2149,7 @@ int journal_file_open_reliably(
|
|||||||
size_t l;
|
size_t l;
|
||||||
char *p;
|
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);
|
metrics, mmap_cache, template, ret);
|
||||||
if (r != -EBADMSG && /* corrupted */
|
if (r != -EBADMSG && /* corrupted */
|
||||||
r != -ENODATA && /* truncated */
|
r != -ENODATA && /* truncated */
|
||||||
@ -2184,7 +2184,7 @@ int journal_file_open_reliably(
|
|||||||
|
|
||||||
log_warning("File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
|
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);
|
metrics, mmap_cache, template, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ typedef struct JournalFile {
|
|||||||
int prot;
|
int prot;
|
||||||
bool writable;
|
bool writable;
|
||||||
bool compress;
|
bool compress;
|
||||||
bool authenticate;
|
bool seal;
|
||||||
|
|
||||||
bool tail_entry_monotonic_valid;
|
bool tail_entry_monotonic_valid;
|
||||||
|
|
||||||
@ -73,17 +73,17 @@ typedef struct JournalFile {
|
|||||||
gcry_md_hd_t hmac;
|
gcry_md_hd_t hmac;
|
||||||
bool hmac_running;
|
bool hmac_running;
|
||||||
|
|
||||||
FSPRGHeader *fsprg_file;
|
FSSHeader *fss_file;
|
||||||
size_t fsprg_file_size;
|
size_t fss_file_size;
|
||||||
|
|
||||||
|
uint64_t fss_start_usec;
|
||||||
|
uint64_t fss_interval_usec;
|
||||||
|
|
||||||
void *fsprg_state;
|
void *fsprg_state;
|
||||||
size_t fsprg_state_size;
|
size_t fsprg_state_size;
|
||||||
|
|
||||||
void *fsprg_seed;
|
void *fsprg_seed;
|
||||||
size_t fsprg_seed_size;
|
size_t fsprg_seed_size;
|
||||||
|
|
||||||
uint64_t fsprg_start_usec;
|
|
||||||
uint64_t fsprg_interval_usec;
|
|
||||||
#endif
|
#endif
|
||||||
} JournalFile;
|
} JournalFile;
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ int journal_file_open(
|
|||||||
int flags,
|
int flags,
|
||||||
mode_t mode,
|
mode_t mode,
|
||||||
bool compress,
|
bool compress,
|
||||||
bool authenticate,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
@ -110,7 +110,7 @@ int journal_file_open_reliably(
|
|||||||
int flags,
|
int flags,
|
||||||
mode_t mode,
|
mode_t mode,
|
||||||
bool compress,
|
bool compress,
|
||||||
bool authenticate,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
@ -152,7 +152,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
|
|||||||
void journal_file_dump(JournalFile *f);
|
void journal_file_dump(JournalFile *f);
|
||||||
void journal_file_print_header(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);
|
void journal_file_post_change(JournalFile *f);
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
* - write tag only if non-tag objects have been written
|
* - write tag only if non-tag objects have been written
|
||||||
* - change terms
|
* - change terms
|
||||||
* - write bit mucking test
|
* - write bit mucking test
|
||||||
|
* - tag timestamps should be between entry timestamps
|
||||||
*
|
*
|
||||||
* - Allow building without libgcrypt
|
* - Allow building without libgcrypt
|
||||||
* - check with sparse
|
* - check with sparse
|
||||||
@ -595,7 +596,7 @@ static int verify_entry_array(
|
|||||||
return 0;
|
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;
|
uint8_t *seed;
|
||||||
size_t seed_size, c;
|
size_t seed_size, c;
|
||||||
const char *k;
|
const char *k;
|
||||||
@ -607,7 +608,7 @@ static int journal_file_parse_seed(JournalFile *f, const char *s) {
|
|||||||
if (!seed)
|
if (!seed)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
k = s;
|
k = key;
|
||||||
for (c = 0; c < seed_size; c++) {
|
for (c = 0; c < seed_size; c++) {
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
@ -644,13 +645,14 @@ static int journal_file_parse_seed(JournalFile *f, const char *s) {
|
|||||||
|
|
||||||
f->fsprg_seed = seed;
|
f->fsprg_seed = seed;
|
||||||
f->fsprg_seed_size = seed_size;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int journal_file_verify(JournalFile *f, const char *seed) {
|
int journal_file_verify(JournalFile *f, const char *key) {
|
||||||
int r;
|
int r;
|
||||||
Object *o;
|
Object *o;
|
||||||
uint64_t p = 0, last_tag = 0, last_epoch = 0;
|
uint64_t p = 0, last_tag = 0, last_epoch = 0;
|
||||||
@ -666,8 +668,8 @@ int journal_file_verify(JournalFile *f, const char *seed) {
|
|||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (seed) {
|
if (key) {
|
||||||
r = journal_file_parse_seed(f, seed);
|
r = journal_file_parse_verification_key(f, key);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_error("Failed to parse seed.");
|
log_error("Failed to parse seed.");
|
||||||
return r;
|
return r;
|
||||||
@ -848,8 +850,8 @@ int journal_file_verify(JournalFile *f, const char *seed) {
|
|||||||
case OBJECT_TAG: {
|
case OBJECT_TAG: {
|
||||||
uint64_t q;
|
uint64_t q;
|
||||||
|
|
||||||
if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED)) {
|
if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED)) {
|
||||||
log_error("Tag object without authentication at %llu", (unsigned long long) p);
|
log_error("Tag object without sealing at %llu", (unsigned long long) p);
|
||||||
r = -EBADMSG;
|
r = -EBADMSG;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -904,7 +906,7 @@ int journal_file_verify(JournalFile *f, const char *seed) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
|
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;
|
r = -EBADMSG;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#include "journal-authenticate.h"
|
#include "journal-authenticate.h"
|
||||||
#include "fsprg.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 OutputMode arg_output = OUTPUT_SHORT;
|
||||||
static bool arg_follow = false;
|
static bool arg_follow = false;
|
||||||
@ -59,8 +59,8 @@ static bool arg_local = false;
|
|||||||
static bool arg_this_boot = false;
|
static bool arg_this_boot = false;
|
||||||
static const char *arg_directory = NULL;
|
static const char *arg_directory = NULL;
|
||||||
static int arg_priorities = 0xFF;
|
static int arg_priorities = 0xFF;
|
||||||
static const char *arg_verify_seed = NULL;
|
static const char *arg_verify_key = NULL;
|
||||||
static usec_t arg_evolve = DEFAULT_FSPRG_INTERVAL_USEC;
|
static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
|
||||||
|
|
||||||
static enum {
|
static enum {
|
||||||
ACTION_SHOW,
|
ACTION_SHOW,
|
||||||
@ -74,27 +74,27 @@ static int help(void) {
|
|||||||
|
|
||||||
printf("%s [OPTIONS...] [MATCH]\n\n"
|
printf("%s [OPTIONS...] [MATCH]\n\n"
|
||||||
"Send control commands to or query the journal.\n\n"
|
"Send control commands to or query the journal.\n\n"
|
||||||
" -h --help Show this help\n"
|
" -h --help Show this help\n"
|
||||||
" --version Show package version\n"
|
" --version Show package version\n"
|
||||||
" --no-pager Do not pipe output into a pager\n"
|
" --no-pager Do not pipe output into a pager\n"
|
||||||
" -a --all Show all fields, including long and unprintable\n"
|
" -a --all Show all fields, including long and unprintable\n"
|
||||||
" -f --follow Follow journal\n"
|
" -f --follow Follow journal\n"
|
||||||
" -n --lines=INTEGER Journal entries to show\n"
|
" -n --lines=INTEGER Journal entries to show\n"
|
||||||
" --no-tail Show all lines, even in follow mode\n"
|
" --no-tail Show all lines, even in follow mode\n"
|
||||||
" -o --output=STRING Change journal output mode (short, short-monotonic,\n"
|
" -o --output=STRING Change journal output mode (short, short-monotonic,\n"
|
||||||
" verbose, export, json, cat)\n"
|
" verbose, export, json, cat)\n"
|
||||||
" -q --quiet Don't show privilege warning\n"
|
" -q --quiet Don't show privilege warning\n"
|
||||||
" -l --local Only local entries\n"
|
" -l --local Only local entries\n"
|
||||||
" -b --this-boot Show data only from current boot\n"
|
" -b --this-boot Show data only from current boot\n"
|
||||||
" -D --directory=PATH Show journal files from directory\n"
|
" -D --directory=PATH Show journal files from directory\n"
|
||||||
" -p --priority=RANGE Show only messages within the specified priority range\n\n"
|
" -p --priority=RANGE Show only messages within the specified priority range\n\n"
|
||||||
"Commands:\n"
|
"Commands:\n"
|
||||||
" --new-id128 Generate a new 128 Bit ID\n"
|
" --new-id128 Generate a new 128 Bit ID\n"
|
||||||
" --header Show journal header information\n"
|
" --header Show journal header information\n"
|
||||||
" --verify Verify journal file consistency\n"
|
" --setup-keys Generate new FSS key pair\n"
|
||||||
" --verify-seed=SEED Specify FSPRG seed for verification\n"
|
" --interval=TIME Time interval for changing the FSS sealing key\n"
|
||||||
" --setup-keys Generate new FSPRG key and seed\n"
|
" --verify Verify journal file consistency\n"
|
||||||
" --evolve=TIME How of to evolve FSPRG keys\n",
|
" --verify-key=KEY Specify FSS verification key\n",
|
||||||
program_invocation_short_name);
|
program_invocation_short_name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -109,32 +109,32 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_NEW_ID128,
|
ARG_NEW_ID128,
|
||||||
ARG_HEADER,
|
ARG_HEADER,
|
||||||
ARG_SETUP_KEYS,
|
ARG_SETUP_KEYS,
|
||||||
|
ARG_INTERVAL,
|
||||||
ARG_VERIFY,
|
ARG_VERIFY,
|
||||||
ARG_VERIFY_SEED,
|
ARG_VERIFY_KEY
|
||||||
ARG_EVOLVE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version" , no_argument, NULL, ARG_VERSION },
|
{ "version" , no_argument, NULL, ARG_VERSION },
|
||||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||||
{ "follow", no_argument, NULL, 'f' },
|
{ "follow", no_argument, NULL, 'f' },
|
||||||
{ "output", required_argument, NULL, 'o' },
|
{ "output", required_argument, NULL, 'o' },
|
||||||
{ "all", no_argument, NULL, 'a' },
|
{ "all", no_argument, NULL, 'a' },
|
||||||
{ "lines", required_argument, NULL, 'n' },
|
{ "lines", required_argument, NULL, 'n' },
|
||||||
{ "no-tail", no_argument, NULL, ARG_NO_TAIL },
|
{ "no-tail", no_argument, NULL, ARG_NO_TAIL },
|
||||||
{ "new-id128", no_argument, NULL, ARG_NEW_ID128 },
|
{ "new-id128", no_argument, NULL, ARG_NEW_ID128 },
|
||||||
{ "quiet", no_argument, NULL, 'q' },
|
{ "quiet", no_argument, NULL, 'q' },
|
||||||
{ "local", no_argument, NULL, 'l' },
|
{ "local", no_argument, NULL, 'l' },
|
||||||
{ "this-boot", no_argument, NULL, 'b' },
|
{ "this-boot", no_argument, NULL, 'b' },
|
||||||
{ "directory", required_argument, NULL, 'D' },
|
{ "directory", required_argument, NULL, 'D' },
|
||||||
{ "header", no_argument, NULL, ARG_HEADER },
|
{ "header", no_argument, NULL, ARG_HEADER },
|
||||||
{ "priority", no_argument, NULL, 'p' },
|
{ "priority", no_argument, NULL, 'p' },
|
||||||
{ "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
|
{ "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
|
||||||
{ "verify", no_argument, NULL, ARG_VERIFY },
|
{ "interval", required_argument, NULL, ARG_INTERVAL },
|
||||||
{ "verify-seed", required_argument, NULL, ARG_VERIFY_SEED },
|
{ "verify", no_argument, NULL, ARG_VERIFY },
|
||||||
{ "evolve", required_argument, NULL, ARG_EVOLVE },
|
{ "verify-key", required_argument, NULL, ARG_VERIFY_KEY },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int c, r;
|
int c, r;
|
||||||
@ -221,15 +221,15 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
arg_action = ACTION_VERIFY;
|
arg_action = ACTION_VERIFY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_VERIFY_SEED:
|
case ARG_VERIFY_KEY:
|
||||||
arg_action = ACTION_VERIFY;
|
arg_action = ACTION_VERIFY;
|
||||||
arg_verify_seed = optarg;
|
arg_verify_key = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_EVOLVE:
|
case ARG_INTERVAL:
|
||||||
r = parse_usec(optarg, &arg_evolve);
|
r = parse_usec(optarg, &arg_interval);
|
||||||
if (r < 0 || arg_evolve <= 0) {
|
if (r < 0 || arg_interval <= 0) {
|
||||||
log_error("Failed to parse evolve interval: %s", optarg);
|
log_error("Failed to parse sealing key change interval: %s", optarg);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -456,7 +456,7 @@ static int setup_keys(void) {
|
|||||||
int fd = -1, r;
|
int fd = -1, r;
|
||||||
sd_id128_t machine, boot;
|
sd_id128_t machine, boot;
|
||||||
char *p = NULL, *k = NULL;
|
char *p = NULL, *k = NULL;
|
||||||
struct FSPRGHeader h;
|
struct FSSHeader h;
|
||||||
uint64_t n;
|
uint64_t n;
|
||||||
|
|
||||||
r = sd_id128_get_machine(&machine);
|
r = sd_id128_get_machine(&machine);
|
||||||
@ -471,7 +471,7 @@ static int setup_keys(void) {
|
|||||||
return r;
|
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)
|
SD_ID128_FORMAT_VAL(machine)) < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
@ -481,7 +481,7 @@ static int setup_keys(void) {
|
|||||||
goto finish;
|
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) {
|
SD_ID128_FORMAT_VAL(machine)) < 0) {
|
||||||
r = log_oom();
|
r = log_oom();
|
||||||
goto finish;
|
goto finish;
|
||||||
@ -514,11 +514,13 @@ static int setup_keys(void) {
|
|||||||
log_info("Generating key pair...");
|
log_info("Generating key pair...");
|
||||||
FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
|
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);
|
FSPRG_GenState0(state, mpk, seed, seed_size);
|
||||||
|
|
||||||
|
assert(arg_interval > 0);
|
||||||
|
|
||||||
n = now(CLOCK_REALTIME);
|
n = now(CLOCK_REALTIME);
|
||||||
n /= arg_evolve;
|
n /= arg_interval;
|
||||||
|
|
||||||
close_nointr_nofail(fd);
|
close_nointr_nofail(fd);
|
||||||
fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY);
|
fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY);
|
||||||
@ -533,10 +535,10 @@ static int setup_keys(void) {
|
|||||||
h.machine_id = machine;
|
h.machine_id = machine;
|
||||||
h.boot_id = boot;
|
h.boot_id = boot;
|
||||||
h.header_size = htole64(sizeof(h));
|
h.header_size = htole64(sizeof(h));
|
||||||
h.fsprg_start_usec = htole64(n * arg_evolve);
|
h.start_usec = htole64(n * arg_interval);
|
||||||
h.fsprg_interval_usec = htole64(arg_evolve);
|
h.interval_usec = htole64(arg_interval);
|
||||||
h.secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
|
h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
|
||||||
h.state_size = htole64(state_size);
|
h.fsprg_state_size = htole64(state_size);
|
||||||
|
|
||||||
l = loop_write(fd, &h, sizeof(h), false);
|
l = loop_write(fd, &h, sizeof(h), false);
|
||||||
if (l < 0 || (size_t) l != sizeof(h)) {
|
if (l < 0 || (size_t) l != sizeof(h)) {
|
||||||
@ -561,14 +563,13 @@ static int setup_keys(void) {
|
|||||||
if (isatty(STDOUT_FILENO)) {
|
if (isatty(STDOUT_FILENO)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n"
|
"\n"
|
||||||
"The new key pair has been generated. The evolving key has been written to the\n"
|
"The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
|
||||||
"following file. It will be used to protect local journal files. This file\n"
|
"the following local file. It should not be used on multiple hosts.\n"
|
||||||
"should be kept secret. It should not be used on multiple hosts.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"\t%s\n"
|
"\t%s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Please write down the following " ANSI_HIGHLIGHT_ON "secret" ANSI_HIGHLIGHT_OFF " seed value. It should not be stored\n"
|
"Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
|
||||||
"locally on disk, and may be used to verify journal files from this host.\n"
|
"at a safe location and should not be saved locally on disk.\n"
|
||||||
"\n\t" ANSI_HIGHLIGHT_RED_ON, p);
|
"\n\t" ANSI_HIGHLIGHT_RED_ON, p);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
@ -578,10 +579,16 @@ static int setup_keys(void) {
|
|||||||
printf("%02x", ((uint8_t*) seed)[i]);
|
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))
|
if (isatty(STDOUT_FILENO)) {
|
||||||
fputs(ANSI_HIGHLIGHT_OFF "\n", stderr);
|
char tsb[FORMAT_TIMESPAN_MAX];
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
ANSI_HIGHLIGHT_OFF "\n"
|
||||||
|
"The sealing key is automatically changed every %s.\n",
|
||||||
|
format_timespan(tsb, sizeof(tsb), arg_interval));
|
||||||
|
}
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
@ -613,13 +620,13 @@ static int verify(sd_journal *j) {
|
|||||||
int k;
|
int k;
|
||||||
|
|
||||||
#ifdef HAVE_GCRYPT
|
#ifdef HAVE_GCRYPT
|
||||||
if (!arg_verify_seed && journal_file_fsprg_enabled(f))
|
if (!arg_verify_key && journal_file_fss_enabled(f))
|
||||||
log_warning("Journal file %s has authentication enabled but verification seed has not been passed using --verify-seed=.", f->path);
|
log_warning("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
k = journal_file_verify(f, arg_verify_seed);
|
k = journal_file_verify(f, arg_verify_key);
|
||||||
if (k == -EINVAL) {
|
if (k == -EINVAL) {
|
||||||
/* If the seed was invalid give up right-away. */
|
/* If the key was invalid give up right-away. */
|
||||||
return k;
|
return k;
|
||||||
} else if (k < 0) {
|
} else if (k < 0) {
|
||||||
log_warning("FAIL: %s (%s)", f->path, strerror(-k));
|
log_warning("FAIL: %s (%s)", f->path, strerror(-k));
|
||||||
|
Loading…
Reference in New Issue
Block a user