aboutsummaryrefslogtreecommitdiffstats
path: root/tests/hypothesis/test_fernet.py
blob: 75195f5304a5bb7059964bc3c4e488579cc89206 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from hypothesis import HealthCheck, given, settings
from hypothesis.strategies import binary

from cryptography.fernet import Fernet


@settings(suppress_health_check=[HealthCheck.too_slow], deadline=None)
@given(binary())
def test_fernet(data):
    f = Fernet(Fernet.generate_key())
    ct = f.encrypt(data)
    assert f.decrypt(ct) == data
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
/******************************************************************************
 *
 * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
 *                    VA Linux Systems Japan K.K.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <xen/types.h>
#include <xen/version.h>
#include <xen/errno.h>
#include <xen/sched.h>

#include <asm/fpswa.h>
#include <asm/dom_fw.h>
#include <asm/dom_fw_common.h>
#include <asm/dom_fw_utils.h>

#include <linux/sort.h>

uint32_t xen_ia64_version(struct domain *unused)
{
	return (xen_major_version() << 16) | xen_minor_version();
}

int xen_ia64_fpswa_revision(struct domain *d, unsigned int *revision)
{
	if (fpswa_interface == NULL)
		return -ENOSYS;

	*revision = fpswa_interface->revision;
	return 0;
}

int xen_ia64_is_vcpu_allocated(struct domain *d, uint32_t vcpu)
{
	return d->vcpu[vcpu] != NULL;
}

int xen_ia64_is_running_on_sim(struct domain *unused)
{
	return running_on_sim;
}

int xen_ia64_is_dom0(struct domain *d)
{
	return d == dom0;
}

static void dom_fw_domain_init(struct domain *d, struct fw_tables *tables)
{
	/* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
	d->arch.efi_runtime = &tables->efi_runtime;
	d->arch.fpswa_inf = &tables->fpswa_inf;
	d->arch.sal_data = &tables->sal_data;
}

static int dom_fw_set_convmem_end(struct domain *d)
{
	unsigned long gpaddr;
	size_t size;
	xen_ia64_memmap_info_t *memmap_info;
	efi_memory_desc_t *md;
	void *p;
	void *memmap_start;
	void *memmap_end;

	if (d->shared_info->arch.memmap_info_pfn == 0)
		return -EINVAL;

	gpaddr = d->shared_info->arch.memmap_info_pfn << PAGE_SHIFT;
	size = d->shared_info->arch.memmap_info_num_pages << PAGE_SHIFT;
	memmap_info = _xmalloc(size, __alignof__(*memmap_info));
	if (memmap_info == NULL)
		return -ENOMEM;
	dom_fw_copy_from(memmap_info, d, gpaddr, size);
	if (memmap_info->efi_memmap_size == 0 ||
	    memmap_info->efi_memdesc_size != sizeof(*md) ||
	    memmap_info->efi_memdesc_version != EFI_MEMORY_DESCRIPTOR_VERSION ||
	    sizeof(*memmap_info) + memmap_info->efi_memmap_size > size ||
	    memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size == 0) {
		xfree(memmap_info);
		return -EINVAL;
	}

	memmap_start = &memmap_info->memdesc;
	memmap_end = memmap_start + memmap_info->efi_memmap_size;

	/* sort it bofore use
	 * XXX: this is created by user space domain builder so that
	 * we should check its integrity */
	sort(&memmap_info->memdesc,
	     memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size,
	     memmap_info->efi_memdesc_size, efi_mdt_cmp, NULL);

	if (d->arch.convmem_end == 0)
		d->arch.convmem_end = d->max_pages << PAGE_SHIFT;

	for (p = memmap_start; p < memmap_end;
	     p += memmap_info->efi_memdesc_size) {
		unsigned long end;

		md = p;
		end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);

		if (md->attribute == EFI_MEMORY_WB &&
		    md->type == EFI_CONVENTIONAL_MEMORY &&
		    md->num_pages > 0 && d->arch.convmem_end < end)
			d->arch.convmem_end = end;
	}

	dom_fw_copy_to(d, gpaddr, memmap_info, size);
	xfree(memmap_info);
	return 0;
}

/* allocate a page for fw
 * guest_setup() @ libxc/xc_linux_build.c does for domU
 */
static inline void
assign_new_domain_page_if_dom0(struct domain *d, unsigned long mpaddr)
{
	if (d == dom0)
		assign_new_domain0_page(d, mpaddr);
}

static void dom_fw_setup_for_domain_restore(domain_t * d, unsigned long maxmem)
{
	assign_new_domain_page(d, FW_HYPERCALL_BASE_PADDR);
	dom_fw_domain_init(d, domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
	d->arch.convmem_end = maxmem;
}

/* copy memory range to domain pseudo physical address space */
void
dom_fw_copy_to(struct domain *d, unsigned long dest_gpaddr,
	       void *src, size_t size)
{
	while (size > 0) {
		unsigned long page_offset = dest_gpaddr & ~PAGE_MASK;
		size_t copy_size = size;
		void *dest;

		if (page_offset + copy_size > PAGE_SIZE)
			copy_size = PAGE_SIZE - page_offset;
		dest = domain_mpa_to_imva(d, dest_gpaddr);
		memcpy(dest, src, copy_size);

		src += copy_size;
		dest_gpaddr += copy_size;
		size -= copy_size;
	}
}

/* copy memory range from domain pseudo physical address space */
void
dom_fw_copy_from(void *dest, struct domain *d, unsigned long src_gpaddr,
		 size_t size)
{
	while (size > 0) {
		unsigned long page_offset = src_gpaddr & ~PAGE_MASK;
		size_t copy_size = size;
		void *src;

		if (page_offset + copy_size > PAGE_SIZE)
			copy_size = PAGE_SIZE - page_offset;
		src = domain_mpa_to_imva(d, src_gpaddr);
		memcpy(dest, src, copy_size);

		dest += copy_size;
		src_gpaddr += copy_size;
		size -= copy_size;
	}
}

int dom_fw_setup(domain_t * d, unsigned long bp_mpa, unsigned long maxmem)
{
	int old_domu_builder = 0;
	struct xen_ia64_boot_param *bp;

	BUILD_BUG_ON(sizeof(struct fw_tables) >
		     (FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR));

	if (bp_mpa == 0) {
		/* bp_mpa == 0 means this is domain restore case. */
		dom_fw_setup_for_domain_restore(d, maxmem);
		return 0;
	}

	/* Create page for boot_param.  */
	assign_new_domain_page_if_dom0(d, bp_mpa);
	bp = domain_mpa_to_imva(d, bp_mpa);
	if (d != dom0) {
		/*
		 * XXX kludge.
		 * when XEN_DOMCTL_arch_setup is called, shared_info can't
		 * be accessed by libxc so that memmap_info_pfn isn't
		 * initialized. But dom_fw_set_convmem_end() requires it, 
		 * so here we initialize it.
		 * note: domain builder may overwrite memmap_info_num_pages,
		 *       memmap_info_pfns later.
		 */
		if (bp->efi_memmap_size == 0 ||
		    XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) == 0 ||
		    XEN_IA64_MEMMAP_INFO_PFN(bp) == 0) {
			/* old domain builder compatibility */
			d->shared_info->arch.memmap_info_num_pages = 1;
			d->shared_info->arch.memmap_info_pfn =
			    (maxmem >> PAGE_SHIFT) - 1;
			old_domu_builder = 1;
		} else {
			d->shared_info->arch.memmap_info_num_pages =
			    XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp);
			d->shared_info->arch.memmap_info_pfn =
			    XEN_IA64_MEMMAP_INFO_PFN(bp);
			/* currently multi page memmap isn't supported */
			if (d->shared_info->arch.memmap_info_num_pages != 1)
				return -ENOSYS;
		}
	}

	/* Create page for acpi tables.  */
	if (d != dom0 && old_domu_builder) {
		struct fake_acpi_tables *imva;
		imva = domain_mpa_to_imva(d, FW_ACPI_BASE_PADDR);
		dom_fw_fake_acpi(d, imva);
	}
	if (d == dom0 || old_domu_builder) {
		int ret;
		unsigned long imva_hypercall_base;
		size_t fw_tables_size;
		struct fw_tables *fw_tables;
		unsigned long gpaddr;

		/* Create page for hypercalls.  */
		assign_new_domain_page_if_dom0(d, FW_HYPERCALL_BASE_PADDR);
		imva_hypercall_base = (unsigned long)domain_mpa_to_imva
		    (d, FW_HYPERCALL_BASE_PADDR);

		/*
		 * dom_fw_init()
		 *   - [FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR)
		 *   - [FW_ACPI_BASE_PADDR, FW_ACPI_END_PADDR)
		 *   - [FW_TABLES_BASE_PADDR, tables->fw_tables_end_paddr)
		 *
		 * complete_dom0_memmap() for dom0
		 *   - real machine memory map
		 *   - memmap_info by setup_dom0_memmap_info()
		 *
		 * complete_domu_memmap() for old domu builder
		 *   - I/O port
		 *   - conventional memory
		 *   - memmap_info
		 */
#define NUM_EXTRA_MEM_DESCS     4

		/* Estimate necessary efi memmap size and allocate memory */
		fw_tables_size = sizeof(*fw_tables) +
			(ia64_boot_param->efi_memmap_size /
			 ia64_boot_param->efi_memdesc_size +
			 NUM_EXTRA_MEM_DESCS) *
			sizeof(fw_tables->efi_memmap[0]);
		if (fw_tables_size <
		    FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR)
			fw_tables_size =
			    FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR;
		fw_tables_size = (fw_tables_size + ((1UL << EFI_PAGE_SHIFT) - 1))
			& ~((1UL << EFI_PAGE_SHIFT) - 1);
		fw_tables =
		    (struct fw_tables *)_xmalloc(fw_tables_size,
						 __alignof__(*fw_tables));
		if (fw_tables == NULL) {
			dprintk(XENLOG_INFO,
				"can't allocate fw_tables memory size = %ld\n",
				fw_tables_size);
			return -ENOMEM;
		}
		memset(fw_tables, 0, fw_tables_size);
		BUILD_BUG_ON(FW_END_PADDR_MIN != FW_TABLES_END_PADDR_MIN);
		fw_tables->fw_tables_size = fw_tables_size;
		fw_tables->fw_end_paddr = FW_TABLES_BASE_PADDR + fw_tables_size;
		fw_tables->fw_tables_end_paddr =
			FW_TABLES_BASE_PADDR + fw_tables_size;
		fw_tables->num_mds = 0;

		/* It is necessary to allocate pages before dom_fw_init()
		 * dom_fw_init() uses up page to d->max_pages.
		 */
		for (gpaddr = FW_TABLES_BASE_PADDR;
		     gpaddr < fw_tables->fw_end_paddr; gpaddr += PAGE_SIZE)
			assign_new_domain_page_if_dom0(d, gpaddr);

		ret = dom_fw_init(d, d->arch.breakimm, bp,
				  fw_tables, imva_hypercall_base, maxmem);
		if (ret < 0) {
			xfree(fw_tables);
			return ret;
		}

		ret = platform_fw_init(d, bp, fw_tables);
		if (ret < 0) {
			xfree(fw_tables);
			return ret;
		}

		if (sizeof(*fw_tables) +
		    fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]) >
		    fw_tables_size) {
			panic("EFI memmap too large. "
			      "Increase NUM_EXTRA_MEM_DESCS.\n"
			      "fw_table_size %ld > %ld num_mds %ld "
			      "NUM_EXTRA_MEM_DESCS %d.\n",
			      fw_tables_size, fw_tables->fw_tables_size,
			      fw_tables->num_mds, NUM_EXTRA_MEM_DESCS);
		}
		fw_tables_size = sizeof(*fw_tables) +
			fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]);

		/* clear domain builder internal use member */
		fw_tables->fw_tables_size = 0;
		fw_tables->fw_end_paddr = 0;
		fw_tables->fw_tables_end_paddr = 0;
		fw_tables->num_mds = 0;

		/* copy fw_tables into domain pseudo physical address space */
		dom_fw_copy_to(d, FW_TABLES_BASE_PADDR, fw_tables,
			       fw_tables_size);
		xfree(fw_tables);
	}

	dom_fw_domain_init(d, domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
	return dom_fw_set_convmem_end(d);
}

/*
 * Local variables:
 * mode: C
 * c-set-style: "linux"
 * c-basic-offset: 8
 * tab-width: 8
 * indent-tabs-mode: t
 * End:
 */