#include "verity.h"
#include "internal.h"
+/* FIXME: not yet final on-disk format! Add UUID etc */
+struct verity_sb {
+ uint8_t signature[8];
+ uint8_t version;
+ uint8_t data_block_bits;
+ uint8_t hash_block_bits;
+ uint8_t pad1[1];
+ uint16_t salt_size;
+ uint8_t pad2[2];
+ uint32_t data_blocks_hi;
+ uint32_t data_blocks_lo;
+ uint8_t algorithm[16];
+ uint8_t salt[VERITY_MAX_SALT_SIZE];
+ uint8_t pad3[88];
+};
+
/* Read verity superblock from disk */
int VERITY_read_sb(struct crypt_device *cd,
const char *device,
- size_t sb_offset,
+ uint64_t sb_offset,
struct crypt_params_verity *params)
{
struct verity_sb sb = {};
ssize_t hdr_size = sizeof(struct verity_sb);
int devfd = 0;
- long long sb_data_blocks;
+ uint64_t sb_data_blocks;
- log_dbg("Reading VERITY header of size %d on device %s, offset %u.",
- sizeof(struct verity_sb), device, (unsigned)sb_offset);
+ log_dbg("Reading VERITY header of size %u on device %s, offset %" PRIu64 ".",
+ sizeof(struct verity_sb), device, sb_offset);
devfd = open(device ,O_RDONLY | O_DIRECT);
if(devfd == -1) {
return -EINVAL;
}
- sb_data_blocks = ((unsigned long long)ntohl(sb.data_blocks_hi) << 31 << 1) |
+ sb_data_blocks = ((uint64_t)ntohl(sb.data_blocks_hi) << 31 << 1) |
ntohl(sb.data_blocks_lo);
- if (sb_data_blocks < 0 ||
- (off_t)sb_data_blocks < 0 ||
- (off_t)sb_data_blocks != sb_data_blocks) {
- log_err(cd, _("VERITY header data block size mismatch.\n"));
- return -EINVAL;
- }
- // FIXME alloc error
params->hash_name = strdup((const char*)sb.algorithm);
+ if (!params->hash_name)
+ return -ENOMEM;
params->data_block_size = 1 << sb.data_block_bits;
params->hash_block_size = 1 << sb.hash_block_bits;
params->data_size = sb_data_blocks;
params->salt_size = ntohs(sb.salt_size);
params->salt = malloc(params->salt_size);
+ if (!params->salt)
+ return -ENOMEM;
memcpy(CONST_CAST(char*)params->salt, sb.salt, params->salt_size);
params->hash_area_offset = sb_offset;
params->version = sb.version;
/* Write verity superblock to disk */
int VERITY_write_sb(struct crypt_device *cd,
const char *device,
- size_t sb_offset,
+ uint64_t sb_offset,
struct crypt_params_verity *params)
{
struct verity_sb sb = {};
ssize_t hdr_size = sizeof(struct verity_sb);
int r, devfd = 0;
- log_dbg("Updating VERITY header of size %d on device %s, offset %u.",
- sizeof(struct verity_sb), device, (unsigned)sb_offset);
+ log_dbg("Updating VERITY header of size %u on device %s, offset %" PRIu64 ".",
+ sizeof(struct verity_sb), device, sb_offset);
devfd = open(device, O_RDWR | O_DIRECT);
if(devfd == -1) {
struct crypt_params_verity *verity_hdr,
uint32_t flags)
{
- struct crypt_dm_active_verity dmd;
+ struct crypt_dm_active_device dmd;
uint64_t offset = 0;
int r;
if (!name)
return 0;
+ dmd.target = DM_VERITY;
dmd.data_device = crypt_get_device_name(cd);
- dmd.hash_device = hash_device;
- dmd.root_hash = root_hash;
- dmd.root_hash_size = root_hash_size;
- dmd.hash_offset = VERITY_hash_offset_block(verity_hdr),
+ dmd.u.verity.hash_device = hash_device;
+ dmd.u.verity.root_hash = root_hash;
+ dmd.u.verity.root_hash_size = root_hash_size;
+ dmd.u.verity.hash_offset = VERITY_hash_offset_block(verity_hdr),
dmd.flags = CRYPT_ACTIVATE_READONLY;
dmd.size = verity_hdr->data_size * verity_hdr->data_block_size / 512;
+ dmd.uuid = NULL;
+ dmd.u.verity.vp = verity_hdr;
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
&dmd.size, &offset, &dmd.flags);
if (r)
return r;
- r = dm_create_verity(name, verity_hdr, &dmd);
+ r = dm_create_device(name, CRYPT_VERITY, &dmd, 0);
if (!r && !(dm_flags() & DM_VERITY_SUPPORTED)) {
log_err(cd, _("Kernel doesn't support dm-verity mapping.\n"));
return -ENOTSUP;