0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering/***
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering This file is part of systemd.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering Copyright 2012 Lennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering systemd is free software; you can redistribute it and/or modify it
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering under the terms of the GNU Lesser General Public License as published by
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering (at your option) any later version.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering systemd is distributed in the hope that it will be useful, but
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering Lesser General Public License for more details.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering You should have received a copy of the GNU Lesser General Public License
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering***/
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include <fcntl.h>
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include <sys/mman.h>
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fsprg.h"
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen#include "hexdecoct.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "journal-authenticate.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include "journal-def.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include "journal-file.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringstatic uint64_t journal_file_tag_seqnum(JournalFile *f) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering uint64_t r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = le64toh(f->header->n_tags) + 1;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering f->header->n_tags = htole64(r);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint journal_file_append_tag(JournalFile *f) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering Object *o;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering uint64_t p;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!f->hmac_running)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f->hmac);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_append_object(f, OBJECT_TAG, sizeof(struct TagObject), &o, &p);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering o->tag.seqnum = htole64(journal_file_tag_seqnum(f));
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering o->tag.epoch = htole64(FSPRG_GetEpoch(f->fsprg_state));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
9f6445e34a57c270f013c9416c123e56261553ddLennart Poettering log_debug("Writing tag %"PRIu64" for epoch %"PRIu64"",
507f22bd0172bff5e5d98145b1419bd472a2c57fZbigniew Jędrzejewski-Szmek le64toh(o->tag.seqnum),
507f22bd0172bff5e5d98145b1419bd472a2c57fZbigniew Jędrzejewski-Szmek FSPRG_GetEpoch(f->fsprg_state));
e627440b41bb0284e4892f7aa9d84c77972487e2Lennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* Add the tag object itself, so that we can protect its
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering * header. This will exclude the actual hash value in it */
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering r = journal_file_hmac_put_object(f, OBJECT_TAG, o, p);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* Get the HMAC tag and store it in the object */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering memcpy(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering f->hmac_running = false;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poetteringint journal_file_hmac_start(JournalFile *f) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (f->hmac_running)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* Prepare HMAC for next cycle */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_reset(f->hmac);
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_setkey(f->hmac, key, sizeof(key));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering f->hmac_running = true;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringstatic int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *epoch) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering uint64_t t;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(epoch);
baed47c3c20512507e497058d388782400a072f6Lennart Poettering assert(f->seal);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (f->fss_start_usec == 0 ||
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fss_interval_usec == 0)
15411c0cb1192799b37ec8f25d6f30e8d7292fc6David Herrmann return -EOPNOTSUPP;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (realtime < f->fss_start_usec)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ESTALE;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering t = realtime - f->fss_start_usec;
baed47c3c20512507e497058d388782400a072f6Lennart Poettering t = t / f->fss_interval_usec;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering *epoch = t;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poetteringstatic int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering uint64_t goal, epoch;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_get_epoch(f, realtime, &goal);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (epoch > goal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ESTALE;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return epoch != goal;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poetteringint journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering uint64_t goal, epoch;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_get_epoch(f, realtime, &goal);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (epoch < goal)
507f22bd0172bff5e5d98145b1419bd472a2c57fZbigniew Jędrzejewski-Szmek log_debug("Evolving FSPRG key from epoch %"PRIu64" to %"PRIu64".", epoch, goal);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering for (;;) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (epoch > goal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ESTALE;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (epoch == goal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering FSPRG_Evolve(f->fsprg_state);
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poetteringint journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering void *msk;
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering uint64_t epoch;
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering assert(f);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering return 0;
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering assert(f->fsprg_seed);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering if (f->fsprg_state) {
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering /* Cheaper... */
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering if (goal == epoch)
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering return 0;
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering if (goal == epoch+1) {
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering FSPRG_Evolve(f->fsprg_state);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering return 0;
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering }
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering } else {
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering f->fsprg_state = malloc(f->fsprg_state_size);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering if (!f->fsprg_state)
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering return -ENOMEM;
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering }
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
507f22bd0172bff5e5d98145b1419bd472a2c57fZbigniew Jędrzejewski-Szmek log_debug("Seeking FSPRG key to %"PRIu64".", goal);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering msk = alloca(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR));
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size);
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering return 0;
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering}
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering if (realtime <= 0)
671e021c92c835c6c701dc61463149d05b6f31afLennart Poettering realtime = now(CLOCK_REALTIME);
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering r = journal_file_fsprg_need_evolve(f, realtime);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r <= 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_append_tag(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering r = journal_file_fsprg_evolve(f, realtime);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
7851983162ef851d5b9ce12bd88de86fc402f88aMichal Schmidtint journal_file_hmac_put_object(JournalFile *f, ObjectType type, Object *o, uint64_t p) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_hmac_start(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering if (!o) {
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering r = journal_file_move_to_object(f, type, p, &o);
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering if (r < 0)
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering return r;
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering } else {
d05089d86ef032b245c7f928e623b88c82998ab0Michal Schmidt if (type > OBJECT_UNUSED && o->object.type != type)
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering return -EBADMSG;
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, o, offsetof(ObjectHeader, payload));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering switch (o->object.type) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering case OBJECT_DATA:
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering /* All but hash and payload are mutable */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, &o->data.hash, sizeof(o->data.hash));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, o->data.payload, le64toh(o->object.size) - offsetof(DataObject, payload));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering break;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
3c1668da6202f1ead3d4d3981b89e9da1a0e98e3Lennart Poettering case OBJECT_FIELD:
3c1668da6202f1ead3d4d3981b89e9da1a0e98e3Lennart Poettering /* Same here */
3c1668da6202f1ead3d4d3981b89e9da1a0e98e3Lennart Poettering gcry_md_write(f->hmac, &o->field.hash, sizeof(o->field.hash));
3c1668da6202f1ead3d4d3981b89e9da1a0e98e3Lennart Poettering gcry_md_write(f->hmac, o->field.payload, le64toh(o->object.size) - offsetof(FieldObject, payload));
3c1668da6202f1ead3d4d3981b89e9da1a0e98e3Lennart Poettering break;
3c1668da6202f1ead3d4d3981b89e9da1a0e98e3Lennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering case OBJECT_ENTRY:
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* All */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, &o->entry.seqnum, le64toh(o->object.size) - offsetof(EntryObject, seqnum));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering break;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering case OBJECT_FIELD_HASH_TABLE:
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering case OBJECT_DATA_HASH_TABLE:
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering case OBJECT_ENTRY_ARRAY:
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* Nothing: everything is mutable */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering break;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering case OBJECT_TAG:
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* All but the tag itself */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, &o->tag.seqnum, sizeof(o->tag.seqnum));
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering gcry_md_write(f->hmac, &o->tag.epoch, sizeof(o->tag.epoch));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering break;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering default:
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -EINVAL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint journal_file_hmac_put_header(JournalFile *f) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_hmac_start(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* All but state+reserved, boot_id, arena_size,
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering * tail_object_offset, n_objects, n_entries,
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering * tail_entry_seqnum, head_entry_seqnum, entry_array_offset,
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering * head_entry_realtime, tail_entry_realtime,
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering * tail_entry_monotonic, n_data, n_fields, n_tags,
14d10188de1fd58e663d73683a400d8d7dc67dbaLennart Poettering * n_entry_arrays. */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, f->header->signature, offsetof(Header, state) - offsetof(Header, signature));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, &f->header->file_id, offsetof(Header, boot_id) - offsetof(Header, file_id));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, &f->header->seqnum_id, offsetof(Header, arena_size) - offsetof(Header, seqnum_id));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_md_write(f->hmac, &f->header->data_hash_table_offset, offsetof(Header, tail_object_offset) - offsetof(Header, data_hash_table_offset));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poetteringint journal_file_fss_load(JournalFile *f) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r, fd = -1;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering char *p = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering struct stat st;
baed47c3c20512507e497058d388782400a072f6Lennart Poettering FSSHeader *m = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering sd_id128_t machine;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = sd_id128_get_machine(&machine);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering SD_ID128_FORMAT_VAL(machine)) < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY, 0600);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (fd < 0) {
272410e1790cb407bcedee4e5dfaac3f625957afLennart Poettering if (errno != ENOENT)
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "Failed to open %s: %m", p);
272410e1790cb407bcedee4e5dfaac3f625957afLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -errno;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (fstat(fd, &st) < 0) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -errno;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (st.st_size < (off_t) sizeof(FSSHeader)) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -ENODATA;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering m = mmap(NULL, PAGE_ALIGN(sizeof(FSSHeader)), PROT_READ, MAP_SHARED, fd, 0);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (m == MAP_FAILED) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering m = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -errno;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (memcmp(m->signature, FSS_HEADER_SIGNATURE, 8) != 0) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -EBADMSG;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (m->incompatible_flags != 0) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -EPROTONOSUPPORT;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (le64toh(m->header_size) < sizeof(FSSHeader)) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -EBADMSG;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
3e4b9b506d676d1cb8692306b38c05f8529e5cdbLennart Poettering if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(le16toh(m->fsprg_secpar))) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -EBADMSG;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fss_file_size = le64toh(m->header_size) + le64toh(m->fsprg_state_size);
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if ((uint64_t) st.st_size < f->fss_file_size) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -ENODATA;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!sd_id128_equal(machine, m->machine_id)) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -EHOSTDOWN;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (le64toh(m->start_usec) <= 0 ||
baed47c3c20512507e497058d388782400a072f6Lennart Poettering le64toh(m->interval_usec) <= 0) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -EBADMSG;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (f->fss_file == MAP_FAILED) {
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fss_file = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = -errno;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering goto finish;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fss_start_usec = le64toh(f->fss_file->start_usec);
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fss_interval_usec = le64toh(f->fss_file->interval_usec);
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fsprg_state = (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size);
baed47c3c20512507e497058d388782400a072f6Lennart Poettering f->fsprg_state_size = le64toh(f->fss_file->fsprg_state_size);
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringfinish:
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (m)
baed47c3c20512507e497058d388782400a072f6Lennart Poettering munmap(m, PAGE_ALIGN(sizeof(FSSHeader)));
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering safe_close(fd);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering free(p);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poetteringstatic void initialize_libgcrypt(void) {
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering const char *p;
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering return;
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering p = gcry_check_version("1.4.5");
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering assert(p);
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering}
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poetteringint journal_file_hmac_setup(JournalFile *f) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering gcry_error_t e;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering initialize_libgcrypt();
72fbdd3349ad30d8a5074ea9a650f0909f96c299Lennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (e != 0)
15411c0cb1192799b37ec8f25d6f30e8d7292fc6David Herrmann return -EOPNOTSUPP;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint journal_file_append_first_tag(JournalFile *f) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering uint64_t p;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
baed47c3c20512507e497058d388782400a072f6Lennart Poettering if (!f->seal)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering log_debug("Calculating first tag...");
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_hmac_put_header(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering p = le64toh(f->header->field_hash_table_offset);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (p < offsetof(Object, hash_table.items))
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -EINVAL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering p -= offsetof(Object, hash_table.items);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering r = journal_file_hmac_put_object(f, OBJECT_FIELD_HASH_TABLE, NULL, p);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering p = le64toh(f->header->data_hash_table_offset);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (p < offsetof(Object, hash_table.items))
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -EINVAL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering p -= offsetof(Object, hash_table.items);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
5996c7c295e073ce21d41305169132c8aa993ad0Lennart Poettering r = journal_file_hmac_put_object(f, OBJECT_DATA_HASH_TABLE, NULL, p);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = journal_file_append_tag(f);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
4da416aa20b956571d74720bc91222881443e24bLennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poetteringint journal_file_parse_verification_key(JournalFile *f, const char *key) {
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering uint8_t *seed;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering size_t seed_size, c;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering const char *k;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering int r;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering unsigned long long start, interval;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering seed_size = FSPRG_RECOMMENDED_SEEDLEN;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering seed = malloc(seed_size);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering if (!seed)
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering return -ENOMEM;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering k = key;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering for (c = 0; c < seed_size; c++) {
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering int x, y;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering while (*k == '-')
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering k++;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering x = unhexchar(*k);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering if (x < 0) {
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering free(seed);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering return -EINVAL;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering }
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering k++;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering y = unhexchar(*k);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering if (y < 0) {
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering free(seed);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering return -EINVAL;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering }
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering k++;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering seed[c] = (uint8_t) (x * 16 + y);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering }
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering if (*k != '/') {
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering free(seed);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering return -EINVAL;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering }
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering k++;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering r = sscanf(k, "%llx-%llx", &start, &interval);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering if (r != 2) {
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering free(seed);
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering return -EINVAL;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering }
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering f->fsprg_seed = seed;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering f->fsprg_seed_size = seed_size;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering f->fss_start_usec = start * interval;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering f->fss_interval_usec = interval;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering return 0;
4da416aa20b956571d74720bc91222881443e24bLennart Poettering}
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poetteringbool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) {
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering uint64_t epoch;
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering assert(f);
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering assert(u);
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering if (!f->seal)
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering return false;
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering epoch = FSPRG_GetEpoch(f->fsprg_state);
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering *u = (usec_t) (f->fss_start_usec + f->fss_interval_usec * epoch + f->fss_interval_usec);
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering return true;
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering}