journal-authenticate.c revision 671e021c92c835c6c701dc61463149d05b6f31af
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2012 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <fcntl.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <sys/mman.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "journal-def.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "journal-file.h"
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#include "journal-authenticate.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "fsprg.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic uint64_t journal_file_tag_seqnum(JournalFile *f) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering uint64_t r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = le64toh(f->header->n_tags) + 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->header->n_tags = htole64(r);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint journal_file_append_tag(JournalFile *f) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Object *o;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint64_t p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!f->seal)
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering return 0;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (!f->hmac_running)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(f->hmac);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_append_object(f, OBJECT_TAG, sizeof(struct TagObject), &o, &p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering o->tag.seqnum = htole64(journal_file_tag_seqnum(f));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering o->tag.epoch = htole64(FSPRG_GetEpoch(f->fsprg_state));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Writing tag %llu for epoch %llu\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (unsigned long long) le64toh(o->tag.seqnum),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (unsigned long long) FSPRG_GetEpoch(f->fsprg_state));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Add the tag object itself, so that we can protect its
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * header. This will exclude the actual hash value in it */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_hmac_put_object(f, OBJECT_TAG, p);
00f0a16ab4576535021456f8955446d3ae8f0b5fLennart Poettering if (r < 0)
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering return r;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Get the HMAC tag and store it in the object */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcpy(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->hmac_running = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringint journal_file_hmac_start(JournalFile *f) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack assert(f);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!f->seal)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return 0;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (f->hmac_running)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering /* Prepare HMAC for next cycle */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering gcry_md_reset(f->hmac);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering gcry_md_setkey(f->hmac, key, sizeof(key));
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering f->hmac_running = true;
6073b6f26ab9fc6bf335faa7073ec443eef093fdTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidtstatic int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *epoch) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering uint64_t t;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(f);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(epoch);
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering assert(f->seal);
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering if (f->fss_start_usec == 0 ||
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering f->fss_interval_usec == 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -ENOTSUP;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if (realtime < f->fss_start_usec)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -ESTALE;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering t = realtime - f->fss_start_usec;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering t = t / f->fss_interval_usec;
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering *epoch = t;
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering return 0;
db97a66aa69925f7403ba3c433e86320d136567dLennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringstatic int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering uint64_t goal, epoch;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt int r;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(f);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!f->seal)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack return 0;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering r = journal_file_get_epoch(f, realtime, &goal);
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering if (r < 0)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack return r;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack epoch = FSPRG_GetEpoch(f->fsprg_state);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack if (epoch > goal)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack return -ESTALE;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack return epoch != goal;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack}
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poetteringint journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) {
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering uint64_t goal, epoch;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack int r;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack assert(f);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack if (!f->seal)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack return 0;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = journal_file_get_epoch(f, realtime, &goal);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return r;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (epoch < goal)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering log_debug("Evolving FSPRG key from epoch %llu to %llu.", (unsigned long long) epoch, (unsigned long long) goal);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering for (;;) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (epoch > goal)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -ESTALE;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (epoch == goal)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering FSPRG_Evolve(f->fsprg_state);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen void *msk;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering uint64_t epoch;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
cc7844e78751916acb639443c119763cafe2c684Lennart Poettering assert(f);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!f->seal)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering assert(f->fsprg_seed);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (f->fsprg_state) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Cheaper... */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
6073b6f26ab9fc6bf335faa7073ec443eef093fdTom Gundersen epoch = FSPRG_GetEpoch(f->fsprg_state);
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen if (goal == epoch)
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen return 0;
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (goal == epoch+1) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering FSPRG_Evolve(f->fsprg_state);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen }
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering } else {
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering f->fsprg_state = malloc(f->fsprg_state_size);
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen if (!f->fsprg_state)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_debug("Seeking FSPRG key to %llu.", (unsigned long long) goal);
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen msk = alloca(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR));
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR);
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen}
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersenint journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(f);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!f->seal)
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (realtime <= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering realtime = now(CLOCK_REALTIME);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_fsprg_need_evolve(f, realtime);
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering if (r <= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_append_tag(f);
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_fsprg_evolve(f, realtime);
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering if (r < 0)
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering return r;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering return 0;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering}
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersenint journal_file_hmac_put_object(JournalFile *f, int type, uint64_t p) {
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering int r;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering Object *o;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering assert(f);
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering if (!f->seal)
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering return 0;
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering r = journal_file_hmac_start(f);
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering if (r < 0)
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering return r;
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering r = journal_file_move_to_object(f, type, p, &o);
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering if (r < 0)
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering return r;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering gcry_md_write(f->hmac, o, offsetof(ObjectHeader, payload));
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering switch (o->object.type) {
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering case OBJECT_DATA:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering /* All but hash and payload are mutable */
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering gcry_md_write(f->hmac, &o->data.hash, sizeof(o->data.hash));
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering gcry_md_write(f->hmac, o->data.payload, le64toh(o->object.size) - offsetof(DataObject, payload));
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering break;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering case OBJECT_ENTRY:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering /* All */
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering gcry_md_write(f->hmac, &o->entry.seqnum, le64toh(o->object.size) - offsetof(EntryObject, seqnum));
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering break;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering case OBJECT_FIELD_HASH_TABLE:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering case OBJECT_DATA_HASH_TABLE:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering case OBJECT_ENTRY_ARRAY:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering /* Nothing: everything is mutable */
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering break;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering case OBJECT_TAG:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering /* All but the tag itself */
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering gcry_md_write(f->hmac, &o->tag.seqnum, sizeof(o->tag.seqnum));
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering gcry_md_write(f->hmac, &o->tag.epoch, sizeof(o->tag.epoch));
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering break;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering default:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering return -EINVAL;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering }
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering return 0;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering}
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poetteringint journal_file_hmac_put_header(JournalFile *f) {
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering int r;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering assert(f);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (!f->seal)
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering return 0;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering r = journal_file_hmac_start(f);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (r < 0)
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering return r;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering /* All but state+reserved, boot_id, arena_size,
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering * tail_object_offset, n_objects, n_entries,
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering * tail_entry_seqnum, head_entry_seqnum, entry_array_offset,
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering * head_entry_realtime, tail_entry_realtime,
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering * tail_entry_monotonic, n_data, n_fields, n_tags,
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering * n_entry_arrays. */
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering gcry_md_write(f->hmac, f->header->signature, offsetof(Header, state) - offsetof(Header, signature));
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering gcry_md_write(f->hmac, &f->header->file_id, offsetof(Header, boot_id) - offsetof(Header, file_id));
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering gcry_md_write(f->hmac, &f->header->seqnum_id, offsetof(Header, arena_size) - offsetof(Header, seqnum_id));
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering gcry_md_write(f->hmac, &f->header->data_hash_table_offset, offsetof(Header, tail_object_offset) - offsetof(Header, data_hash_table_offset));
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering return 0;
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering}
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poetteringint journal_file_fss_load(JournalFile *f) {
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering int r, fd = -1;
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering char *p = NULL;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering struct stat st;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering FSSHeader *m = NULL;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering sd_id128_t machine;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering assert(f);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (!f->seal)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return 0;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = sd_id128_get_machine(&machine);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (r < 0)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return r;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering SD_ID128_FORMAT_VAL(machine)) < 0)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return -ENOMEM;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY, 0600);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (fd < 0) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering log_error("Failed to open %s: %m", p);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = -errno;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering goto finish;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering }
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (fstat(fd, &st) < 0) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = -errno;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering goto finish;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering }
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (st.st_size < (off_t) sizeof(FSSHeader)) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = -ENODATA;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering goto finish;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering }
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering m = mmap(NULL, PAGE_ALIGN(sizeof(FSSHeader)), PROT_READ, MAP_SHARED, fd, 0);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (m == MAP_FAILED) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering m = NULL;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = -errno;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering goto finish;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering }
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (memcmp(m->signature, FSS_HEADER_SIGNATURE, 8) != 0) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = -EBADMSG;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering goto finish;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering if (m->incompatible_flags != 0) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen r = -EPROTONOSUPPORT;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen goto finish;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering if (le64toh(m->header_size) < sizeof(FSSHeader)) {
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering r = -EBADMSG;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering goto finish;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering }
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(le16toh(m->fsprg_secpar))) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen r = -EBADMSG;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering goto finish;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering f->fss_file_size = le64toh(m->header_size) + le64toh(m->fsprg_state_size);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering if ((uint64_t) st.st_size < f->fss_file_size) {
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering r = -ENODATA;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen goto finish;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering if (!sd_id128_equal(machine, m->machine_id)) {
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering r = -EHOSTDOWN;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering goto finish;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering if (le64toh(m->start_usec) <= 0 ||
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering le64toh(m->interval_usec) <= 0) {
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering r = -EBADMSG;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering goto finish;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (f->fss_file == MAP_FAILED) {
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering f->fss_file = NULL;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering r = -errno;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering goto finish;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen f->fss_start_usec = le64toh(f->fss_file->start_usec);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->fss_interval_usec = le64toh(f->fss_file->interval_usec);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering f->fsprg_state = (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->fsprg_state_size = le64toh(f->fss_file->fsprg_state_size);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering r = 0;
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poetteringfinish:
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering if (m)
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering munmap(m, PAGE_ALIGN(sizeof(FSSHeader)));
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering if (fd >= 0)
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering close_nointr_nofail(fd);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering free(p);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering return r;
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering}
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poetteringstatic void initialize_libgcrypt(void) {
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering const char *p;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering p = gcry_check_version("1.4.5");
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering assert(p);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering}
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poetteringint journal_file_hmac_setup(JournalFile *f) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering gcry_error_t e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!f->seal)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering initialize_libgcrypt();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (e != 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOTSUP;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return 0;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering}
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poetteringint journal_file_append_first_tag(JournalFile *f) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint64_t p;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!f->seal)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_debug("Calculating first tag...");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_hmac_put_header(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = le64toh(f->header->field_hash_table_offset);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (p < offsetof(Object, hash_table.items))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EINVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p -= offsetof(Object, hash_table.items);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_hmac_put_object(f, OBJECT_FIELD_HASH_TABLE, p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p = le64toh(f->header->data_hash_table_offset);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (p < offsetof(Object, hash_table.items))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EINVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p -= offsetof(Object, hash_table.items);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = journal_file_hmac_put_object(f, OBJECT_DATA_HASH_TABLE, p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering return r;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering r = journal_file_append_tag(f);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (r < 0)
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering return r;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering return 0;
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering}
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poetteringint journal_file_parse_verification_key(JournalFile *f, const char *key) {
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering uint8_t *seed;
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering size_t seed_size, c;
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering const char *k;
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering int r;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering unsigned long long start, interval;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering seed_size = FSPRG_RECOMMENDED_SEEDLEN;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering seed = malloc(seed_size);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!seed)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering k = key;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (c = 0; c < seed_size; c++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int x, y;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering while (*k == '-')
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering x = unhexchar(*k);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (x < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(seed);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EINVAL;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering }
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering k++;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering y = unhexchar(*k);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (y < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(seed);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EINVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering k++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering seed[c] = (uint8_t) (x * 16 + y);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (*k != '/') {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(seed);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EINVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sscanf(k, "%llx-%llx", &start, &interval);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r != 2) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(seed);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EINVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->fsprg_seed = seed;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->fsprg_seed_size = seed_size;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->fss_start_usec = start * interval;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f->fss_interval_usec = interval;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringbool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint64_t epoch;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering assert(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!f->seal)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return false;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering *u = (usec_t) (f->fss_start_usec + f->fss_interval_usec * epoch + f->fss_interval_usec);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return true;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering