Пример #1
0
int LUKS_wipe_header_areas(struct luks_phdr *hdr,
	struct crypt_device *ctx)
{
	int i, r;
	uint64_t offset, length;
	size_t wipe_block;

	/* Wipe complete header, keyslots and padding areas with zeroes. */
	offset = 0;
	length = (uint64_t)hdr->payloadOffset * SECTOR_SIZE;
	wipe_block = 1024 * 1024;

	/* On detached header or bogus header, wipe at least the first 4k */
	if (length == 0 || length > (LUKS_MAX_KEYSLOT_SIZE * LUKS_NUMKEYS)) {
		length = 4096;
		wipe_block = 4096;
	}

	log_dbg(ctx, "Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
		offset, length + offset);

	r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_ZERO,
			      offset, length, wipe_block, NULL, NULL);
	if (r < 0)
		return r;

	/* Wipe keyslots areas */
	wipe_block = 1024 * 1024;
	for (i = 0; i < LUKS_NUMKEYS; i++) {
		r = LUKS_keyslot_area(hdr, i, &offset, &length);
		if (r < 0)
			return r;

		/* Ignore too big LUKS1 keyslots here */
		if (length > LUKS_MAX_KEYSLOT_SIZE ||
		    offset > (LUKS_MAX_KEYSLOT_SIZE - length))
			continue;

		if (length == 0 || offset < 4096)
			return -EINVAL;

		log_dbg(ctx, "Wiping keyslot %i area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
			i, offset, length + offset);

		r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_RANDOM,
				offset, length, wipe_block, NULL, NULL);
		if (r < 0)
			return r;
	}

	return r;
}
static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struct json_object **keyslot_object)
{
	char *base64_str, cipher[LUKS_CIPHERNAME_L+LUKS_CIPHERMODE_L];
	size_t base64_len;
	struct json_object *keyslot_obj, *field, *jobj_kdf, *jobj_af, *jobj_area;
	uint64_t offset, area_size, offs_a, offs_b, length;

	keyslot_obj = json_object_new_object();
	json_object_object_add(keyslot_obj, "type", json_object_new_string("luks2"));
	json_object_object_add(keyslot_obj, "key_size", json_object_new_int64(hdr_v1->keyBytes));

	/* KDF */
	jobj_kdf = json_object_new_object();
	json_object_object_add(jobj_kdf, "type", json_object_new_string(CRYPT_KDF_PBKDF2));
	json_object_object_add(jobj_kdf, "hash", json_object_new_string(hdr_v1->hashSpec));
	json_object_object_add(jobj_kdf, "iterations", json_object_new_int64(hdr_v1->keyblock[keyslot].passwordIterations));
	/* salt field */
	base64_len = base64_encode_alloc(hdr_v1->keyblock[keyslot].passwordSalt, LUKS_SALTSIZE, &base64_str);
	if (!base64_str) {
		json_object_put(keyslot_obj);
		json_object_put(jobj_kdf);
		if (!base64_len)
			return -EINVAL;
		return -ENOMEM;
	}
	field = json_object_new_string_len(base64_str, base64_len);
	free(base64_str);
	json_object_object_add(jobj_kdf, "salt", field);
	json_object_object_add(keyslot_obj, "kdf", jobj_kdf);

	/* AF */
	jobj_af = json_object_new_object();
	json_object_object_add(jobj_af, "type", json_object_new_string("luks1"));
	json_object_object_add(jobj_af, "hash", json_object_new_string(hdr_v1->hashSpec));
	/* stripes field ignored, fixed to LUKS_STRIPES (4000) */
	json_object_object_add(jobj_af, "stripes", json_object_new_int(4000));
	json_object_object_add(keyslot_obj, "af", jobj_af);

	/* Area */
	jobj_area = json_object_new_object();
	json_object_object_add(jobj_area, "type", json_object_new_string("raw"));

	/* encryption algorithm field */
	if (*hdr_v1->cipherMode != '\0') {
		(void) snprintf(cipher, sizeof(cipher), "%s-%s", hdr_v1->cipherName, hdr_v1->cipherMode);
		json_object_object_add(jobj_area, "encryption", json_object_new_string(cipher));
	} else
		json_object_object_add(jobj_area, "encryption", json_object_new_string(hdr_v1->cipherName));

	/* area */
	if (LUKS_keyslot_area(hdr_v1, 0, &offs_a, &length) ||
	    LUKS_keyslot_area(hdr_v1, 1, &offs_b, &length) ||
	    LUKS_keyslot_area(hdr_v1, keyslot, &offset, &length)) {
		json_object_put(keyslot_obj);
		json_object_put(jobj_area);
		return -EINVAL;
	}
	area_size = offs_b - offs_a;
	json_object_object_add(jobj_area, "key_size", json_object_new_int(hdr_v1->keyBytes));
	json_object_object_add(jobj_area, "offset", json_object_new_uint64(offset));
	json_object_object_add(jobj_area, "size", json_object_new_uint64(area_size));
	json_object_object_add(keyslot_obj, "area", jobj_area);

	*keyslot_object = keyslot_obj;
	return 0;
}