static int TCRYPT_hdr_from_disk(struct tcrypt_phdr *hdr,
				struct crypt_params_tcrypt *params,
				int kdf_index, int cipher_index)
{
	uint32_t crc32;
	size_t size;

	/* Check CRC32 of header */
	size = TCRYPT_HDR_LEN - sizeof(hdr->d.keys) - sizeof(hdr->d.header_crc32);
	crc32 = crypt_crc32(~0, (unsigned char*)&hdr->d, size) ^ ~0;
	if (be16_to_cpu(hdr->d.version) > 3 &&
	    crc32 != be32_to_cpu(hdr->d.header_crc32)) {
		log_dbg("TCRYPT header CRC32 mismatch.");
		return -EINVAL;
	}

	/* Check CRC32 of keys */
	crc32 = crypt_crc32(~0, (unsigned char*)hdr->d.keys, sizeof(hdr->d.keys)) ^ ~0;
	if (crc32 != be32_to_cpu(hdr->d.keys_crc32)) {
		log_dbg("TCRYPT keys CRC32 mismatch.");
		return -EINVAL;
	}

	/* Convert header to cpu format */
	hdr->d.version  =  be16_to_cpu(hdr->d.version);
	hdr->d.version_tc = be16_to_cpu(hdr->d.version_tc);

	hdr->d.keys_crc32 = be32_to_cpu(hdr->d.keys_crc32);

	hdr->d.hidden_volume_size = be64_to_cpu(hdr->d.hidden_volume_size);
	hdr->d.volume_size        = be64_to_cpu(hdr->d.volume_size);

	hdr->d.mk_offset = be64_to_cpu(hdr->d.mk_offset);
	if (!hdr->d.mk_offset)
		hdr->d.mk_offset = 512;

	hdr->d.mk_size = be64_to_cpu(hdr->d.mk_size);

	hdr->d.flags = be32_to_cpu(hdr->d.flags);

	hdr->d.sector_size = be32_to_cpu(hdr->d.sector_size);
	if (!hdr->d.sector_size)
		hdr->d.sector_size = 512;

	hdr->d.header_crc32 = be32_to_cpu(hdr->d.header_crc32);

	/* Set params */
	params->passphrase = NULL;
	params->passphrase_size = 0;
	params->hash_name  = tcrypt_kdf[kdf_index].hash;
	params->key_size = tcrypt_cipher[cipher_index].chain_key_size;
	params->cipher = tcrypt_cipher[cipher_index].long_name;
	params->mode = tcrypt_cipher[cipher_index].mode;

	return 0;
}
Exemple #2
0
static int TCRYPT_pool_keyfile(struct crypt_device *cd,
				unsigned char pool[TCRYPT_KEY_POOL_LEN],
				const char *keyfile)
{
	unsigned char data[TCRYPT_KEYFILE_LEN];
	int i, j, fd, data_size;
	uint32_t crc;

	log_dbg("TCRYPT: using keyfile %s.", keyfile);

	fd = open(keyfile, O_RDONLY);
	if (fd < 0) {
		log_err(cd, _("Failed to open key file.\n"));
		return -EIO;
	}

	/* FIXME: add while */
	data_size = read(fd, data, TCRYPT_KEYFILE_LEN);
	close(fd);
	if (data_size < 0) {
		log_err(cd, _("Error reading keyfile %s.\n"), keyfile);
		return -EIO;
	}

	for (i = 0, j = 0, crc = ~0U; i < data_size; i++) {
		crc = crypt_crc32(crc, &data[i], 1);
		pool[j++] += (unsigned char)(crc >> 24);
		pool[j++] += (unsigned char)(crc >> 16);
		pool[j++] += (unsigned char)(crc >>  8);
		pool[j++] += (unsigned char)(crc);
		j %= TCRYPT_KEY_POOL_LEN;
	}

	memset(&crc, 0, sizeof(crc));
	memset(data, 0, TCRYPT_KEYFILE_LEN);

	return 0;
}