Пример #1
0
/*
 * Calculate per-link MAC by pathname
 */
static int32_t calc_link_mac_v1(struct mtd_format_v1 *fmt,
				loc_t *loc,
				unsigned char *result,
				struct crypt_inode_info *info,
				struct master_cipher_info *master)
{
	int32_t ret;
	unsigned char nmtd_link_key[16];
	CMAC_CTX *cctx;
	size_t len;

	ret = get_nmtd_link_key(loc, master, nmtd_link_key);
	if (ret) {
		gf_log("crypt", GF_LOG_ERROR, "Can not get nmtd link key");
		return -1;
	}
	cctx = CMAC_CTX_new();
	if (!cctx) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_CTX_new failed");
		return -1;
	}
	ret = CMAC_Init(cctx, nmtd_link_key, sizeof(nmtd_link_key),
			EVP_aes_128_cbc(), 0);
	if (!ret) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_Init failed");
		CMAC_CTX_free(cctx);
		return -1;
	}
	ret = CMAC_Update(cctx, get_NMTD_V1(info), SIZE_OF_NMTD_V1);
	if (!ret) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_Update failed");
		CMAC_CTX_free(cctx);
		return -1;
	}
	ret = CMAC_Final(cctx, result, &len);
	CMAC_CTX_free(cctx);
	if (!ret) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_Final failed");
		return -1;
	}
	return 0;
}
Пример #2
0
static int32_t create_format_v1(unsigned char *wire,
				loc_t *loc,
				struct crypt_inode_info *info,
				struct master_cipher_info *master)
{
	int32_t ret;
	struct mtd_format_v1 *fmt;
	unsigned char mtd_key[16];
	AES_KEY EMTD_KEY;
	unsigned char nmtd_link_key[16];
	uint32_t ad;
	GCM128_CONTEXT *gctx;

	fmt = (struct mtd_format_v1 *)wire;

	fmt->minor_id = info->nr_minor;
	fmt->alg_id = AES_CIPHER_ALG;
	fmt->dkey_factor = master->m_dkey_size >> KEY_FACTOR_BITS;
	fmt->block_bits = master->m_block_bits;
	fmt->mode_id = master->m_mode;
	/*
	 * retrieve keys for the parts of metadata
	 */
	ret = get_emtd_file_key(info, master, mtd_key);
	if (ret)
		return ret;
	ret = get_nmtd_link_key(loc, master, nmtd_link_key);
	if (ret)
		return ret;
	
	AES_set_encrypt_key(mtd_key, sizeof(mtd_key)*8, &EMTD_KEY);

	gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt);

	/* TBD: Check return values */

	CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t));

	ad = htole32(MTD_LOADER_V1);
	ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad));
	if (ret) {
		gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed");
		CRYPTO_gcm128_release(gctx);
		return ret;
	}
	ret = CRYPTO_gcm128_encrypt(gctx,
				    get_EMTD_V1(fmt),
				    get_EMTD_V1(fmt),
				    SIZE_OF_EMTD_V1);
	if (ret) {
		gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_encrypt failed");
		CRYPTO_gcm128_release(gctx);
		return ret;
	}
	/*
	 * set MAC of encrypted part of metadata
	 */
	CRYPTO_gcm128_tag(gctx, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC);
	CRYPTO_gcm128_release(gctx);
	/*
	 * set the first MAC of non-encrypted part of metadata 
	 */
	return create_link_mac_v1(fmt, 0, loc, info, master);
}