Example #1
0
int device_block_size(struct device *device)
{
	struct stat st;
	int fd, bsize = 0, r = -EINVAL;

	if (!device)
		return 0;

	fd = open(device->path, O_RDONLY);
	if(fd < 0)
		return -EINVAL;

	if (fstat(fd, &st) < 0)
		goto out;

	if (S_ISREG(st.st_mode) || device->file_path) {
		r = (int)crypt_getpagesize();
		goto out;
	}

	if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
		r = bsize;
out:
	close(fd);
	return r;
}
Example #2
0
/* Create verity hash */
int VERITY_create(struct crypt_device *cd,
		  struct crypt_params_verity *verity_hdr,
		  char *root_hash,
		  size_t root_hash_size)
{
	unsigned pgsize = crypt_getpagesize();

	if (verity_hdr->salt_size > 256)
		return -EINVAL;

	if (verity_hdr->data_block_size > pgsize)
		log_err(cd, "WARNING: Kernel cannot activate device if data "
			      "block size exceeds page size (%u).\n", pgsize);

    off_t sz = verity_hdr->data_size;
	return VERITY_create_or_verify_hash(cd, 0,
		verity_hdr->hash_type,
		verity_hdr->hash_name,
		crypt_metadata_device(cd),
		crypt_data_device(cd),
		verity_hdr->hash_block_size,
		verity_hdr->data_block_size,
		verity_hdr->data_size,
		VERITY_hash_offset_block(verity_hdr),
		root_hash,
		root_hash_size,
		verity_hdr->salt,
		verity_hdr->salt_size);
}
Example #3
0
static int cipher_perf(struct cipher_perf *cp,
	double *encryption_mbs, double *decryption_mbs)
{
	long ms_enc, ms_dec, ms;
	int repeat_enc, repeat_dec;
	void *buf = NULL;

	if (posix_memalign(&buf, crypt_getpagesize(), cp->buffer_size))
		return -ENOMEM;

	ms_enc = 0;
	repeat_enc = 1;
	while (ms_enc < 1000) {
		ms = cipher_measure(cp, buf, cp->buffer_size, 1);
		if (ms < 0) {
			free(buf);
			return (int)ms;
		}
		ms_enc += ms;
		repeat_enc++;
	}

	ms_dec = 0;
	repeat_dec = 1;
	while (ms_dec < 1000) {
		ms = cipher_measure(cp, buf, cp->buffer_size, 0);
		if (ms < 0) {
			free(buf);
			return (int)ms;
		}
		ms_dec += ms;
		repeat_dec++;
	}

	free(buf);

	*encryption_mbs = speed_mbs(cp->buffer_size * repeat_enc, ms_enc);
	*decryption_mbs = speed_mbs(cp->buffer_size * repeat_dec, ms_dec);

	return  0;
}
Example #4
0
int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
{
	struct device *device = crypt_metadata_device(ctx);
	struct luks_phdr hdr;
	int r = 0, devfd = -1;
	ssize_t hdr_size;
	ssize_t buffer_size;
	char *buffer = NULL;

	r = LUKS_read_phdr(&hdr, 1, 0, ctx);
	if (r)
		return r;

	hdr_size = LUKS_device_sectors(hdr.keyBytes) << SECTOR_SHIFT;
	buffer_size = size_round_up(hdr_size, crypt_getpagesize());

	buffer = crypt_safe_alloc(buffer_size);
	if (!buffer || hdr_size < LUKS_ALIGN_KEYSLOTS || hdr_size > buffer_size) {
		r = -ENOMEM;
		goto out;
	}

	log_dbg("Storing backup of header (%zu bytes) and keyslot area (%zu bytes).",
		sizeof(hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);

	log_dbg("Output backup file size: %zu bytes.", buffer_size);

	devfd = device_open(device, O_RDONLY);
	if(devfd == -1) {
		log_err(ctx, _("Device %s is not a valid LUKS device.\n"), device_path(device));
		r = -EINVAL;
		goto out;
	}

	if (read_blockwise(devfd, device_block_size(device), buffer, hdr_size) < hdr_size) {
		r = -EIO;
		goto out;
	}
	close(devfd);

	/* Wipe unused area, so backup cannot contain old signatures */
	if (hdr.keyblock[0].keyMaterialOffset * SECTOR_SIZE == LUKS_ALIGN_KEYSLOTS)
		memset(buffer + sizeof(hdr), 0, LUKS_ALIGN_KEYSLOTS - sizeof(hdr));

	devfd = open(backup_file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR);
	if (devfd == -1) {
		if (errno == EEXIST)
			log_err(ctx, _("Requested header backup file %s already exists.\n"), backup_file);
		else
			log_err(ctx, _("Cannot create header backup file %s.\n"), backup_file);
		r = -EINVAL;
		goto out;
	}
	if (write(devfd, buffer, buffer_size) < buffer_size) {
		log_err(ctx, _("Cannot write header backup file %s.\n"), backup_file);
		r = -EIO;
		goto out;
	}
	close(devfd);

	r = 0;
out:
	if (devfd != -1)
		close(devfd);
	crypt_memzero(&hdr, sizeof(hdr));
	crypt_safe_free(buffer);
	return r;
}
Example #5
0
static int TCRYPT_init_hdr(struct crypt_device *cd,
			   struct tcrypt_phdr *hdr,
			   struct crypt_params_tcrypt *params)
{
	unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
	size_t passphrase_size;
	char *key;
	unsigned int i, skipped = 0;
	int r = -EPERM;

	if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
		return -ENOMEM;

	if (params->keyfiles_count)
		passphrase_size = TCRYPT_KEY_POOL_LEN;
	else
		passphrase_size = params->passphrase_size;

	if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
		log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded.\n"),
			      TCRYPT_KEY_POOL_LEN);
		goto out;
	}

	/* Calculate pool content from keyfiles */
	for (i = 0; i < params->keyfiles_count; i++) {
		r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
		if (r < 0)
			goto out;
	}

	/* If provided password, combine it with pool */
	for (i = 0; i < params->passphrase_size; i++)
		pwd[i] += params->passphrase[i];

	for (i = 0; tcrypt_kdf[i].name; i++) {
		if (!(params->flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_kdf[i].legacy)
			continue;
		if (!(params->flags & CRYPT_TCRYPT_VERA_MODES) && tcrypt_kdf[i].veracrypt)
			continue;
		/* Derive header key */
		log_dbg("TCRYPT: trying KDF: %s-%s-%d.",
			tcrypt_kdf[i].name, tcrypt_kdf[i].hash, tcrypt_kdf[i].iterations);
		r = crypt_pbkdf(tcrypt_kdf[i].name, tcrypt_kdf[i].hash,
				(char*)pwd, passphrase_size,
				hdr->salt, TCRYPT_HDR_SALT_LEN,
				key, TCRYPT_HDR_KEY_LEN,
				tcrypt_kdf[i].iterations);
		if (r < 0 && crypt_hash_size(tcrypt_kdf[i].hash) < 0) {
			log_verbose(cd, _("PBKDF2 hash algorithm %s not available, skipping.\n"),
				      tcrypt_kdf[i].hash);
			continue;
		}
		if (r < 0)
			break;

		/* Decrypt header */
		r = TCRYPT_decrypt_hdr(cd, hdr, key, params->flags);
		if (r == -ENOENT) {
			skipped++;
			r = -EPERM;
		}
		if (r != -EPERM)
			break;
	}

	if ((r < 0 && r != -EPERM && skipped && skipped == i) || r == -ENOTSUP) {
		log_err(cd, _("Required kernel crypto interface not available.\n"));
#ifdef ENABLE_AF_ALG
		log_err(cd, _("Ensure you have algif_skcipher kernel module loaded.\n"));
#endif
	}
	if (r < 0)
		goto out;

	r = TCRYPT_hdr_from_disk(hdr, params, i, r);
	if (!r) {
		log_dbg("TCRYPT: Magic: %s, Header version: %d, req. %d, sector %d"
			", mk_offset %" PRIu64 ", hidden_size %" PRIu64
			", volume size %" PRIu64, tcrypt_kdf[i].veracrypt ?
			VCRYPT_HDR_MAGIC : TCRYPT_HDR_MAGIC,
			(int)hdr->d.version, (int)hdr->d.version_tc, (int)hdr->d.sector_size,
			hdr->d.mk_offset, hdr->d.hidden_volume_size, hdr->d.volume_size);
		log_dbg("TCRYPT: Header cipher %s-%s, key size %zu",
			params->cipher, params->mode, params->key_size);
	}
out:
	crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
	if (key)
		crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
	free(key);
	return r;
}